Added airline sample

This commit is contained in:
Arjen Poutsma
2013-11-22 12:38:04 +01:00
parent 1753df9eff
commit fa2119a3af
85 changed files with 4823 additions and 0 deletions

View File

@@ -10,6 +10,8 @@ The following sample applications demonstrate the capabilities of [Spring Web
Services]. See the README within each sample project for more information and
additional instructions.
- [airline](./airline) - a complete airline sample that shows both Web Service and
O/X Mapping functionality in a complete application
- [echo](./echo) - a simple sample that shows a bare-bones Echo service
- [mtom](./mtom) - shows how to use MTOM and JAXB2 marshalling
- [stockquote](./stockquote) - shows how to use WS-Addressing and the Java 6 HTTP Server

18
airline/README.md Normal file
View File

@@ -0,0 +1,18 @@
# Airline Sample
Features a web service on top of an airline reservation system, backed by a
database. The web service works by using XML Marshalling techniques (JAXB2),
and XPath in combination with XPath queries to pull information from a message.
Additionally, the Airline service has JMS support. All messages follow the
messages.xsd schema in src/main/webapp.
## Build and deploy
See the main [README](../README.md) for build instructions.
## License
[Spring Web Services] is released under version 2.0 of the [Apache License].
[Spring Web Services]: http://projects.spring.io/spring-ws
[Apache License]: http://www.apache.org/licenses/LICENSE-2.0

19
airline/build.gradle Normal file
View File

@@ -0,0 +1,19 @@
subprojects {
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
repositories {
maven { url 'http://repo.spring.io/libs-release' }
}
dependencies {
testCompile("junit:junit:4.10")
testCompile("org.easymock:easymock:3.1")
}
}
task wrapper(type: Wrapper) {
gradleVersion = '1.8'
}

View File

@@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?><wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:sch0="http://www.springframework.org/spring-ws/samples/airline/schemas/messages" xmlns:sch1="http://www.springframework.org/spring-ws/samples/airline/schemas/types" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.springframework.org/spring-ws/samples/airline/definitions" targetNamespace="http://www.springframework.org/spring-ws/samples/airline/definitions">
<wsdl:types>
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.springframework.org/spring-ws/samples/airline/schemas/messages" xmlns:types="http://www.springframework.org/spring-ws/samples/airline/schemas/types" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.springframework.org/spring-ws/samples/airline/schemas/messages"><import namespace="http://www.springframework.org/spring-ws/samples/airline/schemas/types"/><element name="GetFlightsRequest"><complexType><all><element name="from" type="types:AirportCode"/><element name="to" type="types:AirportCode"/><element name="departureDate" type="date"/><element minOccurs="0" name="serviceClass" type="types:ServiceClass"/></all></complexType></element><element name="GetFlightsResponse"><complexType><sequence><element maxOccurs="unbounded" minOccurs="0" name="flight" type="types:Flight"/></sequence></complexType></element><element name="BookFlightRequest"><complexType><all><element name="flightNumber" type="types:FlightNumber"/><element name="departureTime" type="dateTime"/><element name="passengers"><complexType><choice maxOccurs="9"><element name="passenger" type="types:Name"/><element name="username" type="types:FrequentFlyerUsername"/></choice></complexType></element></all></complexType></element><element name="BookFlightResponse" type="types:Ticket"/><element name="GetFrequentFlyerMileageRequest" nillable="true" type="string"/><element name="GetFrequentFlyerMileageResponse" type="int"/></schema>
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.springframework.org/spring-ws/samples/airline/schemas/types" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.springframework.org/spring-ws/samples/airline/schemas/types"><complexType name="Flight"><sequence><element name="number" type="tns:FlightNumber"/><element name="departureTime" type="dateTime"/><element name="from" type="tns:Airport"/><element name="arrivalTime" type="dateTime"/><element name="to" type="tns:Airport"/><element name="serviceClass" type="tns:ServiceClass"/></sequence></complexType><simpleType name="FlightNumber"><restriction base="string"><pattern value="[A-Z][A-Z][0-9][0-9][0-9][0-9]"/></restriction></simpleType><complexType name="Name"><sequence><element name="first" type="string"/><element name="last" type="string"/></sequence></complexType><simpleType name="FrequentFlyerUsername"><restriction base="string"/></simpleType><complexType name="Airport"><all><element name="code" type="tns:AirportCode"/><element name="name" type="string"/><element name="city" type="string"/></all></complexType><simpleType name="AirportCode"><restriction base="string"><pattern value="[A-Z][A-Z][A-Z]"/></restriction></simpleType><complexType name="Ticket"><all><element name="id" type="long"/><element name="issueDate" type="date"/><element name="passengers"><complexType><sequence><element maxOccurs="9" name="passenger" type="tns:Name"/></sequence></complexType></element><element name="flight" type="tns:Flight"/></all></complexType><simpleType name="ServiceClass"><restriction base="NCName"><enumeration value="economy"/><enumeration value="business"/><enumeration value="first"/></restriction></simpleType></schema>
</wsdl:types>
<wsdl:message name="BookFlightRequest">
<wsdl:part element="sch0:BookFlightRequest" name="BookFlightRequest">
</wsdl:part>
</wsdl:message>
<wsdl:message name="GetFlightsResponse">
<wsdl:part element="sch0:GetFlightsResponse" name="GetFlightsResponse">
</wsdl:part>
</wsdl:message>
<wsdl:message name="BookFlightResponse">
<wsdl:part element="sch0:BookFlightResponse" name="BookFlightResponse">
</wsdl:part>
</wsdl:message>
<wsdl:message name="GetFrequentFlyerMileageRequest">
<wsdl:part element="sch0:GetFrequentFlyerMileageRequest" name="GetFrequentFlyerMileageRequest">
</wsdl:part>
</wsdl:message>
<wsdl:message name="GetFlightsRequest">
<wsdl:part element="sch0:GetFlightsRequest" name="GetFlightsRequest">
</wsdl:part>
</wsdl:message>
<wsdl:message name="GetFrequentFlyerMileageResponse">
<wsdl:part element="sch0:GetFrequentFlyerMileageResponse" name="GetFrequentFlyerMileageResponse">
</wsdl:part>
</wsdl:message>
<wsdl:portType name="Airline">
<wsdl:operation name="BookFlight">
<wsdl:input message="tns:BookFlightRequest" name="BookFlightRequest">
</wsdl:input>
<wsdl:output message="tns:BookFlightResponse" name="BookFlightResponse">
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="GetFlights">
<wsdl:input message="tns:GetFlightsRequest" name="GetFlightsRequest">
</wsdl:input>
<wsdl:output message="tns:GetFlightsResponse" name="GetFlightsResponse">
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="GetFrequentFlyerMileage">
<wsdl:input message="tns:GetFrequentFlyerMileageRequest" name="GetFrequentFlyerMileageRequest">
</wsdl:input>
<wsdl:output message="tns:GetFrequentFlyerMileageResponse" name="GetFrequentFlyerMileageResponse">
</wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="AirlineSoap11" type="tns:Airline">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="BookFlight">
<soap:operation soapAction=""/>
<wsdl:input name="BookFlightRequest">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="BookFlightResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="GetFlights">
<soap:operation soapAction=""/>
<wsdl:input name="GetFlightsRequest">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="GetFlightsResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="GetFrequentFlyerMileage">
<soap:operation soapAction=""/>
<wsdl:input name="GetFrequentFlyerMileageRequest">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="GetFrequentFlyerMileageResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="AirlineService">
<wsdl:port binding="tns:AirlineSoap11" name="AirlineSoap11">
<soap:address location="http://localhost:8080/airline-server/services"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

View File

@@ -0,0 +1,62 @@
configurations {
axis
}
ext.axisVersion = '1.4'
task axis {
ext.sourcesDir = "${buildDir}/generated-sources/axis"
ext.classesDir = "${buildDir}/classes/axis"
ext.wsdl = "${projectDir}/../airline.wsdl"
inputs.files wsdl
outputs.dir classesDir
doLast() {
project.ant {
taskdef name: "axis", classname: "org.apache.axis.tools.ant.wsdl.Wsdl2javaAntTask",
classpath: configurations.axis.asPath
mkdir(dir: sourcesDir)
mkdir(dir: classesDir)
axis(output: sourcesDir, url: wsdl) {
mapping(namespace: "http://www.springframework.org/spring-ws/samples/airline/definitions",
package: "org.springframework.ws.samples.airline.client.axis1")
mapping(namespace: "http://www.springframework.org/spring-ws/samples/airline/schemas/messages",
package: "org.springframework.ws.samples.airline.client.axis1")
mapping(namespace: "http://www.springframework.org/spring-ws/samples/airline/schemas/types",
package: "org.springframework.ws.samples.airline.client.axis1")
}
javac(destdir: classesDir, source: 1.6, target: 1.6, debug: true,
debugLevel: "lines,vars,source",
classpath: configurations.axis.asPath) {
src(path: sourcesDir)
include(name: "**/*.java")
include(name: "*.java")
}
copy(todir: classesDir) {
fileset(dir: sourcesDir, erroronmissingdir: false) {
exclude(name: "**/*.java")
}
}
}
}
}
dependencies {
compile("axis:axis:$axisVersion")
compile("axis:axis-jaxrpc:$axisVersion")
compile(files(axis.classesDir).builtBy(axis))
runtime("log4j:log4j:1.2.16")
axis("axis:axis:$axisVersion")
axis("axis:axis-ant:$axisVersion")
}
task runClient(dependsOn: 'classes', type:JavaExec) {
main = "org.springframework.ws.samples.airline.client.axis1.Main"
classpath = sourceSets.main.runtimeClasspath
}

View File

@@ -0,0 +1,10 @@
SPRING WEB SERVICES
This directory contains a Java client for the Airline Web Service that uses JAX-RPC.
The client can be run from the provided ant file, by calling "ant run".
SAJA Client Sample table of contents
---------------------------------------------------
* src - The source files for the client
* build.xml - Ant build file with a 'build' and a 'run' target

View File

@@ -0,0 +1,94 @@
/*
* Copyright 2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.client.axis1;
import java.rmi.RemoteException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Calendar;
import javax.xml.rpc.ServiceException;
/**
* Simple client that calls the <code>GetFlights</code> and <code>BookFlight</code> operations using JAX-RPC (Axis 1).
*
* @author Arjen Poutsma
*/
public class Main {
public static void main(String[] args) throws ServiceException, RemoteException {
AirlineServiceLocator service = new AirlineServiceLocator();
if (args.length > 0) {
service.setAirlineSoap11EndpointAddress(args[0]);
}
Airline airline = service.getAirlineSoap11();
GetFlightsRequest request = new GetFlightsRequest();
request.setFrom("AMS");
request.setTo("VCE");
Calendar departureCalendar = Calendar.getInstance();
departureCalendar.set(Calendar.YEAR, 2006);
departureCalendar.set(Calendar.MONTH, Calendar.JANUARY);
departureCalendar.set(Calendar.DATE, 31);
Date departureDate = departureCalendar.getTime();
request.setDepartureDate(departureDate);
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
System.out.println("Requesting flights on " + dateFormat.format(departureDate));
Flight[] flights = airline.getFlights(request);
System.out.println("Got " + flights.length + " results");
if (flights.length > 0)
{
// Book the first flight using John Doe as a frequent flyer
BookFlightRequest bookFlightRequest = new BookFlightRequest();
bookFlightRequest.setFlightNumber(flights[0].getNumber());
bookFlightRequest.setDepartureTime(flights[0].getDepartureTime());
BookFlightRequestPassengers passengers = new BookFlightRequestPassengers();
passengers.setUsername("john");
bookFlightRequest.setPassengers(passengers);
Ticket ticket = airline.bookFlight(bookFlightRequest);
writeTicket(ticket);
}
}
private static void writeTicket(Ticket ticket) {
System.out.println("Ticket " + ticket.getId());
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
System.out.println("Ticket issue date:\t" + dateFormat.format(ticket.getIssueDate()));
for (int i = 0; i < ticket.getPassengers().length; i++) {
writeName(ticket.getPassengers()[i]);
}
writeFlight(ticket.getFlight());
}
private static void writeName(Name name) {
System.out.println("Passenger Name:");
System.out.println(name.getFirst() + " " + name.getLast());
System.out.println("------------");
}
private static void writeFlight(Flight flight) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
System.out.println(dateFormat.format(flight.getDepartureTime().getTime()));
System.out.println(flight.getNumber() + "\t" + flight.getServiceClass());
System.out.println("------------");
System.out.println("Depart:\t" + flight.getFrom().getCode() + "-" + flight.getFrom().getName() + "\t" + dateFormat.format(flight.getDepartureTime().getTime()));
System.out.println("\t" + flight.getFrom().getCity());
System.out.println("Arrive:\t" + flight.getTo().getCode() + "-" + flight.getTo().getName() + "\t" + dateFormat.format(flight.getArrivalTime().getTime()));
System.out.println("\t" + flight.getTo().getCity());
}
}

View File

@@ -0,0 +1,7 @@
log4j.rootLogger=WARN, stdout
log4j.logger.org.springframework.ws=DEBUG
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n

View File

@@ -0,0 +1,38 @@
configurations {
wsimport
}
ext.springWsVersion = '2.1.4.RELEASE'
task wsImport {
ext.outputDir = "${buildDir}/classes/wsimport"
ext.wsdl = "${projectDir}/../airline.wsdl"
inputs.files wsdl
outputs.dir outputDir
doLast() {
project.ant {
taskdef name: "wsimport", classname: "com.sun.tools.ws.ant.WsImport",
classpath: configurations.wsimport.asPath
mkdir(dir: outputDir)
wsimport(destdir: outputDir, wsdl: wsdl,
package: "org.springframework.ws.samples.airline.client.jaxws") {
produces(dir: outputDir, includes: "**/*.class")
}
}
}
}
dependencies {
compile("org.springframework.ws:spring-ws-core:$springWsVersion")
compile(files(wsImport.outputDir).builtBy(wsImport))
runtime("log4j:log4j:1.2.16")
wsimport "com.sun.xml.ws:jaxws-tools:2.1.7"
}
task runClient(dependsOn: 'classes', type:JavaExec) {
main = "org.springframework.ws.samples.airline.client.jaxws.Main"
classpath = sourceSets.main.runtimeClasspath
}

View File

@@ -0,0 +1,11 @@
SPRING WEB SERVICES
This directory contains a Java client for the Airline Web Service that uses JAX-WS.
The client can be run from the provided ant file, by calling "ant run".
Note that the airline sample has to be running before invoking this target.
Client Sample table of contents
---------------------------------------------------
* src - The source files for the client
* build.xml - Ant build file with a 'build' and a 'run' target

View File

@@ -0,0 +1,104 @@
/*
* Copyright 2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.client.jaxws;
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeConstants;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.namespace.QName;
import javax.xml.ws.soap.SOAPFaultException;
/**
* Simple client that calls the <code>GetFlights</code> and <code>BookFlight</code> operations using JAX-WS.
*
* @author Arjen Poutsma
*/
public class Main {
public static void main(String[] args) throws MalformedURLException, DatatypeConfigurationException {
try {
AirlineService service;
if (args.length == 0) {
service = new AirlineService();
}
else {
QName serviceName = new QName("http://www.springframework.org/spring-ws/samples/airline/definitions",
"AirlineService");
service = new AirlineService(new URL(args[0]), serviceName);
}
Airline airline = service.getAirlineSoap11();
GetFlightsRequest request = new GetFlightsRequest();
request.setFrom("AMS");
request.setTo("VCE");
XMLGregorianCalendar departureDate =
DatatypeFactory.newInstance().newXMLGregorianCalendarDate(2006, 1, 31,
DatatypeConstants.FIELD_UNDEFINED);
request.setDepartureDate(departureDate);
System.out.format("Requesting flights on %1tD%n", departureDate.toGregorianCalendar());
GetFlightsResponse response = airline.getFlights(request);
System.out.format("Got %1d results%n", response.getFlight().size());
if (!response.getFlight().isEmpty())
// Book the first flight using John Doe as a frequent flyer
{
Flight flight = response.getFlight().get(0);
BookFlightRequest bookFlightRequest = new BookFlightRequest();
bookFlightRequest.setFlightNumber(flight.getNumber());
bookFlightRequest.setDepartureTime(flight.getDepartureTime());
BookFlightRequest.Passengers passengers = new BookFlightRequest.Passengers();
passengers.getPassengerOrUsername().add("john");
bookFlightRequest.setPassengers(passengers);
Ticket ticket = airline.bookFlight(bookFlightRequest);
writeTicket(ticket);
}
}
catch (SOAPFaultException ex) {
System.out.format("SOAP Fault Code %1s%n", ex.getFault().getFaultCodeAsQName());
System.out.format("SOAP Fault String: %1s%n", ex.getFault().getFaultString());
}
}
private static void writeTicket(Ticket ticket) {
System.out.format("Ticket %1d%n", ticket.getId());
System.out.format("Ticket issue date:\t%1tD%n", ticket.getIssueDate().toGregorianCalendar());
for (Name passenger : ticket.getPassengers().getPassenger()) {
writeName(passenger);
}
writeFlight(ticket.flight);
}
private static void writeName(Name name) {
System.out.format("Passenger Name:%n");
System.out.format("%1s %2s%n", name.getFirst(), name.getLast());
System.out.format("------------%n");
}
private static void writeFlight(Flight flight) {
System.out.format("%1tD%n", flight.getDepartureTime().toGregorianCalendar());
System.out.format("%1s\t%2s%n", flight.getNumber(), flight.getServiceClass());
System.out.format("------------%n");
System.out.format("Depart:\t%1s-%2s\t%tR%n", flight.getFrom().getCode(), flight.getFrom().getName(), flight.getDepartureTime().toGregorianCalendar());
System.out.format("\t%1s%n", flight.getFrom().getCity());
System.out.format("Arrive:\t%1s-%2s\t%tR%n", flight.getTo().getCode(), flight.getTo().getName(), flight.getArrivalTime().toGregorianCalendar());
System.out.format("\t%1s%n", flight.getTo().getCity());
}
}

View File

@@ -0,0 +1,14 @@
ext.springWsVersion = '2.1.4.RELEASE'
dependencies {
compile("org.springframework.ws:spring-ws-core:$springWsVersion")
compile("org.springframework.ws:spring-ws-support:$springWsVersion")
compile("org.apache.geronimo.specs:geronimo-jms_1.1_spec:1.1")
runtime("log4j:log4j:1.2.16")
runtime("org.apache.activemq:activemq-core:4.1.2")
}
task runClient(dependsOn: 'classes', type:JavaExec) {
main = "org.springframework.ws.samples.airline.client.jms.JmsClient"
classpath = sourceSets.main.runtimeClasspath
}

View File

@@ -0,0 +1,10 @@
SPRING WEB SERVICES
This directory contains a client for the Airline Web Service that uses JMS: Java Message Service. The client can be run
from the provided ant file, by calling "ant run".
JMS Client Sample table of contents
---------------------------------------------------
* src - The source files for the client
* build.xml - Ant build file with a 'build' and a 'run' target

View File

@@ -0,0 +1,48 @@
/*
* Copyright 2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.client.jms;
import java.io.IOException;
import javax.jms.JMSException;
import javax.xml.soap.SOAPException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.stream.StreamResult;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.ws.client.core.support.WebServiceGatewaySupport;
import org.springframework.xml.transform.StringSource;
/** @author Arjen Poutsma */
public class JmsClient extends WebServiceGatewaySupport {
private static final String PAYLOAD =
"<airline:GetFlightsRequest xmlns:airline=\"http://www.springframework.org/spring-ws/samples/airline/schemas/messages\">" +
"<airline:from>AMS</airline:from>" + "<airline:to>VCE</airline:to>" +
"<airline:departureDate>2006-01-31</airline:departureDate>" + "</airline:GetFlightsRequest>";
public void getFlights() throws SOAPException, IOException, TransformerException, JMSException {
getWebServiceTemplate().sendSourceAndReceiveToResult(new StringSource(PAYLOAD), new StreamResult(System.out));
}
public static void main(String[] args) throws Exception {
ApplicationContext applicationContext =
new ClassPathXmlApplicationContext("applicationContext.xml", JmsClient.class);
JmsClient jmsClient = (JmsClient) applicationContext.getBean("jmsClient", JmsClient.class);
jmsClient.getFlights();
}
}

View File

@@ -0,0 +1,7 @@
log4j.rootLogger=WARN, stdout
log4j.logger.org.springframework.ws=DEBUG
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://localhost:61616"/>
</bean>
<bean id="jmsClient" class="org.springframework.ws.samples.airline.client.jms.JmsClient">
<property name="defaultUri" value="jms:RequestQueue"/>
<property name="messageSenders">
<bean class="org.springframework.ws.transport.jms.JmsMessageSender">
<property name="connectionFactory" ref="connectionFactory"/>
</bean>
</property>
</bean>
</beans>

View File

@@ -0,0 +1,10 @@
dependencies {
compile("com.sun.xml.wss:xws-security:3.0") {
exclude group: 'javax.xml.crypto', module: 'xmldsig'
}
}
task runClient(dependsOn: 'classes', type:JavaExec) {
main = "org.springframework.ws.samples.airline.client.saaj.Driver"
classpath = sourceSets.main.runtimeClasspath
}

View File

@@ -0,0 +1,11 @@
SPRING WEB SERVICES
This directory contains two Java clients for the Airline Web Service that use SAAJ: SOAP with Attachments API for Java.
There is a client for the GetFlights operation and a client for the secure GetFrequentFlyerMileage operation. Both
clients can be run from the provided ant file, by calling "ant run".
SAJA Client Sample table of contents
---------------------------------------------------
* src - The source files for the client
* build.xml - Ant build file with a 'build' and a 'run' target

View File

@@ -0,0 +1,38 @@
/*
* Copyright 2005-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.client.saaj;
/**
* @author Arjen Poutsma
*/
public class Driver {
public static void main(String[] args) throws Exception {
String url = "http://localhost:8080/airline-server/services";
if (args.length > 0) {
url = args[0];
}
GetFlights getFlights = new GetFlights(url);
getFlights.getFlights();
String username = "john";
String password = "changeme";
GetFrequentFlyerMileage getMileage = new GetFrequentFlyerMileage(url);
getMileage.getMileage(username, password);
}
}

View File

@@ -0,0 +1,117 @@
/*
* Copyright 2005-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.client.saaj;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Iterator;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.Name;
import javax.xml.soap.SOAPBodyElement;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFault;
import javax.xml.soap.SOAPMessage;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
/**
* Simple client that calls the <code>GetFlights</code> operation using SAAJ.
*
* @author Arjen Poutsma
*/
public class GetFlights {
public static final String NAMESPACE_URI = "http://www.springframework.org/spring-ws/samples/airline/schemas/messages";
public static final String PREFIX = "airline";
private SOAPConnectionFactory connectionFactory;
private MessageFactory messageFactory;
private URL url;
private TransformerFactory transfomerFactory;
public GetFlights(String url) throws SOAPException, MalformedURLException {
connectionFactory = SOAPConnectionFactory.newInstance();
messageFactory = MessageFactory.newInstance();
transfomerFactory = TransformerFactory.newInstance();
this.url = new URL(url);
}
private SOAPMessage createGetFlightsRequest() throws SOAPException {
SOAPMessage message = messageFactory.createMessage();
SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();
Name getFlightsRequestName = envelope.createName("GetFlightsRequest", PREFIX, NAMESPACE_URI);
SOAPBodyElement getFlightsRequestElement = message.getSOAPBody().addBodyElement(getFlightsRequestName);
Name fromName = envelope.createName("from", PREFIX, NAMESPACE_URI);
SOAPElement fromElement = getFlightsRequestElement.addChildElement(fromName);
fromElement.setValue("AMS");
Name toName = envelope.createName("to", PREFIX, NAMESPACE_URI);
SOAPElement toElement = getFlightsRequestElement.addChildElement(toName);
toElement.setValue("VCE");
Name departureDateName = envelope.createName("departureDate", PREFIX, NAMESPACE_URI);
SOAPElement departureDateElement = getFlightsRequestElement.addChildElement(departureDateName);
departureDateElement.setValue("2006-01-31");
return message;
}
public void getFlights() throws SOAPException, IOException, TransformerException {
SOAPMessage request = createGetFlightsRequest();
SOAPConnection connection = connectionFactory.createConnection();
SOAPMessage response = connection.call(request, url);
if (!response.getSOAPBody().hasFault()) {
writeGetFlightsResponse(response);
}
else {
SOAPFault fault = response.getSOAPBody().getFault();
System.err.println("Received SOAP Fault");
System.err.println("SOAP Fault Code: " + fault.getFaultCode());
System.err.println("SOAP Fault String: " + fault.getFaultString());
}
}
private void writeGetFlightsResponse(SOAPMessage message) throws SOAPException, TransformerException {
SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();
Name getFlightsResponseName = envelope.createName("GetFlightsResponse", PREFIX, NAMESPACE_URI);
SOAPBodyElement getFlightsResponseElement =
(SOAPBodyElement) message.getSOAPBody().getChildElements(getFlightsResponseName).next();
Name flightName = envelope.createName("flight", PREFIX, NAMESPACE_URI);
Iterator iterator = getFlightsResponseElement.getChildElements(flightName);
Transformer transformer = transfomerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
int count = 1;
while (iterator.hasNext()) {
System.out.println("Flight " + count);
System.out.println("--------");
SOAPElement flightElement = (SOAPElement) iterator.next();
DOMSource source = new DOMSource(flightElement);
transformer.transform(source, new StreamResult(System.out));
}
}
}

View File

@@ -0,0 +1,128 @@
/*
* Copyright 2005-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.client.saaj;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.Name;
import javax.xml.soap.SOAPBodyElement;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFault;
import javax.xml.soap.SOAPMessage;
import com.sun.xml.wss.ProcessingContext;
import com.sun.xml.wss.XWSSProcessor;
import com.sun.xml.wss.XWSSProcessorFactory;
import com.sun.xml.wss.XWSSecurityException;
import com.sun.xml.wss.impl.callback.PasswordCallback;
import com.sun.xml.wss.impl.callback.UsernameCallback;
/**
* Simple client that calls the WS-Security <code>GetFrequentFlyerMileage</code> operation using SAAJ and XWSS.
*
* @author Arjen Poutsma
*/
public class GetFrequentFlyerMileage {
public static final String NAMESPACE_URI = "http://www.springframework.org/spring-ws/samples/airline/schemas/messages";
public static final String PREFIX = "airline";
private SOAPConnectionFactory connectionFactory;
private MessageFactory messageFactory;
private URL url;
private XWSSProcessorFactory processorFactory;
public GetFrequentFlyerMileage(String url) throws SOAPException, MalformedURLException, XWSSecurityException {
connectionFactory = SOAPConnectionFactory.newInstance();
messageFactory = MessageFactory.newInstance();
processorFactory = XWSSProcessorFactory.newInstance();
this.url = new URL(url);
}
private SOAPMessage createGetMileageRequest() throws SOAPException {
SOAPMessage message = messageFactory.createMessage();
SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();
Name getFlightsRequestName = envelope.createName("GetFrequentFlyerMileageRequest", GetFrequentFlyerMileage.PREFIX,
GetFrequentFlyerMileage.NAMESPACE_URI);
message.getSOAPBody().addBodyElement(getFlightsRequestName);
return message;
}
private SOAPMessage secureMessage(SOAPMessage message, final String username, final String password)
throws IOException, XWSSecurityException {
CallbackHandler callbackHandler = new CallbackHandler() {
public void handle(Callback[] callbacks) throws UnsupportedCallbackException {
for (int i = 0; i < callbacks.length; i++) {
if (callbacks[i] instanceof UsernameCallback) {
UsernameCallback callback = (UsernameCallback) callbacks[i];
callback.setUsername(username);
}
else if (callbacks[i] instanceof PasswordCallback) {
PasswordCallback callback = (PasswordCallback) callbacks[i];
callback.setPassword(password);
}
else {
throw new UnsupportedCallbackException(callbacks[i]);
}
}
}
};
InputStream policyStream = null;
XWSSProcessor processor = null;
try {
policyStream = getClass().getResourceAsStream("securityPolicy.xml");
processor = processorFactory.createProcessorForSecurityConfiguration(policyStream, callbackHandler);
}
finally {
if (policyStream != null) {
policyStream.close();
}
}
ProcessingContext context = processor.createProcessingContext(message);
return processor.secureOutboundMessage(context);
}
public void getMileage(String username, String password) throws SOAPException, IOException, XWSSecurityException {
SOAPMessage request = createGetMileageRequest();
request = secureMessage(request, username, password);
SOAPConnection connection = connectionFactory.createConnection();
SOAPMessage response = connection.call(request, url);
if (!response.getSOAPBody().hasFault()) {
SOAPBodyElement mileage = (SOAPBodyElement) response.getSOAPBody().getChildElements().next();
System.out.println("'" + username + "' has " + mileage.getValue() + " frequent flyer miles");
}
else {
SOAPFault fault = response.getSOAPBody().getFault();
System.err.println("Received SOAP Fault");
System.err.println("SOAP Fault Code: " + fault.getFaultCode());
System.err.println("SOAP Fault String: " + fault.getFaultString());
}
}
}

View File

@@ -0,0 +1,3 @@
<xwss:SecurityConfiguration dumpMessages="false" xmlns:xwss="http://java.sun.com/xml/ns/xwss/config">
<xwss:UsernameToken digestPassword="true" useNonce="true"/>
</xwss:SecurityConfiguration>

View File

@@ -0,0 +1,46 @@
configurations {
xmlbeans
}
ext.springWsVersion = '2.1.4.RELEASE'
task xmlbeans {
ext.schema = "${projectDir}/../../server/src/main/webapp/messages.xsd"
ext.classesDir = "${buildDir}/classes/xmlbeans"
inputs.files schema
outputs.dir classesDir
doLast() {
project.ant {
taskdef name: "xmlbeans",
classname: "org.apache.xmlbeans.impl.tool.XMLBean",
classpath: configurations.xmlbeans.asPath
xmlbeans(classgendir: classesDir, schema: schema,
compiler: "modern", verbose: "false",
classpath: configurations.xmlbeans.asPath)
}
}
}
dependencies {
compile(files(xmlbeans.classesDir).builtBy(xmlbeans))
compile("org.apache.xmlbeans:xmlbeans:2.4.0")
compile("org.springframework.ws:spring-ws-core:$springWsVersion")
runtime("org.springframework.ws:spring-ws-security:$springWsVersion") {
exclude group: 'com.sun.xml.wsit', module: 'wsit-rt'
exclude group: 'com.sun.xml.wsit', module: 'xws-security'
}
runtime("com.sun.xml.wss:xws-security:3.0") {
exclude group: 'javax.xml.crypto', module: 'xmldsig'
}
runtime("log4j:log4j:1.2.16")
testCompile("org.springframework.ws:spring-ws-test:$springWsVersion")
xmlbeans("org.apache.xmlbeans:xmlbeans:2.4.0")
}
task runClient(dependsOn: 'classes', type:JavaExec) {
main = "org.springframework.ws.samples.airline.client.sws.Driver"
classpath = sourceSets.main.runtimeClasspath
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright 2005-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.client.sws;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author Arjen Poutsma
*/
public class Driver {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"org/springframework/ws/samples/airline/client/sws/applicationContext.xml");
GetFlights getFlights = applicationContext.getBean("getFlights", GetFlights.class);
getFlights.getFlights();
GetFrequentFlyerMileage getFrequentFlyerMileage = applicationContext
.getBean("getFrequentFlyerMileage", GetFrequentFlyerMileage.class);
getFrequentFlyerMileage.getFrequentFlyerMileage();
}
}

View File

@@ -0,0 +1,102 @@
/*
* Copyright 2005-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.client.sws;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import org.springframework.springWs.samples.airline.schemas.messages.BookFlightRequestDocument;
import org.springframework.springWs.samples.airline.schemas.messages.BookFlightResponseDocument;
import org.springframework.springWs.samples.airline.schemas.messages.GetFlightsRequestDocument;
import org.springframework.springWs.samples.airline.schemas.messages.GetFlightsResponseDocument;
import org.springframework.springWs.samples.airline.schemas.types.Flight;
import org.springframework.springWs.samples.airline.schemas.types.Name;
import org.springframework.springWs.samples.airline.schemas.types.Ticket;
import org.springframework.ws.WebServiceMessageFactory;
import org.springframework.ws.client.core.support.WebServiceGatewaySupport;
public class GetFlights extends WebServiceGatewaySupport {
public GetFlights(WebServiceMessageFactory messageFactory) {
super(messageFactory);
}
public void getFlights() {
GetFlightsRequestDocument getFlightsRequestDocument = GetFlightsRequestDocument.Factory.newInstance();
GetFlightsRequestDocument.GetFlightsRequest getFlightsRequest =
getFlightsRequestDocument.addNewGetFlightsRequest();
getFlightsRequest.setFrom("AMS");
getFlightsRequest.setTo("VCE");
Calendar departureDate = Calendar.getInstance();
departureDate.clear();
departureDate.set(2006, Calendar.JANUARY, 31);
getFlightsRequest.setDepartureDate(departureDate);
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
System.out.println("Requesting flights on " + dateFormat.format(departureDate.getTime()));
GetFlightsResponseDocument getFlightsResponseDocument =
(GetFlightsResponseDocument) getWebServiceTemplate().marshalSendAndReceive(getFlightsRequestDocument);
GetFlightsResponseDocument.GetFlightsResponse response = getFlightsResponseDocument.getGetFlightsResponse();
System.out.println("Got " + response.sizeOfFlightArray() + " results");
if (response.sizeOfFlightArray() > 0) {
// Book the first flight using John Doe as a frequent flyer
BookFlightRequestDocument bookFlightRequestDocument = BookFlightRequestDocument.Factory.newInstance();
BookFlightRequestDocument.BookFlightRequest bookFlightRequest =
bookFlightRequestDocument.addNewBookFlightRequest();
bookFlightRequest.setFlightNumber(response.getFlightArray(0).getNumber());
bookFlightRequest.setDepartureTime(response.getFlightArray(0).getDepartureTime());
BookFlightRequestDocument.BookFlightRequest.Passengers passengers = bookFlightRequest.addNewPassengers();
passengers.addUsername("john");
BookFlightResponseDocument bookFlightResponseDocument = (BookFlightResponseDocument) getWebServiceTemplate()
.marshalSendAndReceive(bookFlightRequestDocument);
Ticket ticket = bookFlightResponseDocument.getBookFlightResponse();
writeTicket(ticket);
}
}
private void writeTicket(Ticket ticket) {
System.out.println("Ticket " + ticket.getId());
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
System.out.println("Ticket issue date:\t" + dateFormat.format(ticket.getIssueDate().getTime()));
for (int i = 0; i < ticket.getPassengers().sizeOfPassengerArray(); i++) {
writeName(ticket.getPassengers().getPassengerArray(i));
}
writeFlight(ticket.getFlight());
}
private void writeName(Name name) {
System.out.println("Passenger Name:");
System.out.println(name.getFirst() + " " + name.getLast());
System.out.println("------------");
}
private void writeFlight(Flight flight) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
System.out.println(dateFormat.format(flight.getDepartureTime().getTime()));
System.out.println(flight.getNumber() + "\t" + flight.getServiceClass());
System.out.println("------------");
System.out.println("Depart:\t" + flight.getFrom().getCode() + "-" + flight.getFrom().getName() + "\t" +
dateFormat.format(flight.getDepartureTime().getTime()));
System.out.println("\t" + flight.getFrom().getCity());
System.out.println("Arrive:\t" + flight.getTo().getCode() + "-" + flight.getTo().getName() + "\t" +
dateFormat.format(flight.getArrivalTime().getTime()));
System.out.println("\t" + flight.getTo().getCity());
}
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright 2005-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.client.sws;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamResult;
import org.springframework.ws.WebServiceMessageFactory;
import org.springframework.ws.client.core.support.WebServiceGatewaySupport;
import org.springframework.xml.transform.StringSource;
public class GetFrequentFlyerMileage extends WebServiceGatewaySupport {
public GetFrequentFlyerMileage(WebServiceMessageFactory messageFactory) {
super(messageFactory);
}
public void getFrequentFlyerMileage() {
Source source = new StringSource(
"<GetFrequentFlyerMileageRequest xmlns=\"http://www.springframework.org/spring-ws/samples/airline/schemas/messages\" />");
getWebServiceTemplate().sendSourceAndReceiveToResult(source, new StreamResult(System.out));
}
}

View File

@@ -0,0 +1,7 @@
log4j.rootLogger=WARN, stdout
log4j.logger.org.springframework.ws=DEBUG
log4j.logger.org.springframework.xml=DEBUG
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory"/>
<bean id="abstractClient" abstract="true">
<constructor-arg ref="messageFactory"/>
<property name="defaultUri" value="http://localhost:8080/airline-server/services"/>
</bean>
<bean id="marshaller" class="org.springframework.oxm.xmlbeans.XmlBeansMarshaller"/>
<bean id="getFlights" parent="abstractClient" class="org.springframework.ws.samples.airline.client.sws.GetFlights">
<property name="marshaller" ref="marshaller"/>
<property name="unmarshaller" ref="marshaller"/>
</bean>
<bean id="getFrequentFlyerMileage" parent="abstractClient"
class="org.springframework.ws.samples.airline.client.sws.GetFrequentFlyerMileage">
<property name="interceptors" ref="securityInterceptor"/>
</bean>
<bean id="securityInterceptor" class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
<property name="securementActions" value="UsernameToken"/>
<property name="securementUsername" value="john"/>
<property name="securementPassword" value="changeme"/>
</bean>
</beans>

View File

@@ -0,0 +1,3 @@
<xwss:SecurityConfiguration dumpMessages="false" xmlns:xwss="http://java.sun.com/xml/ns/xwss/config">
<xwss:UsernameToken digestPassword="true" useNonce="true"/>
</xwss:SecurityConfiguration>

View File

@@ -0,0 +1,100 @@
/*
* Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.client.sws;
import java.util.Collections;
import java.util.Map;
import javax.xml.transform.Source;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.xml.transform.StringSource;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.ws.test.client.MockWebServiceServer;
import static org.springframework.ws.test.client.RequestMatchers.*;
import static org.springframework.ws.test.client.ResponseCreators.*;
/**
* This test illustrates the use of the client-side testing API, introduced in Spring-WS 2.0.
*
* @author Arjen Poutsma
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("applicationContext.xml")
public class GetFlightsTest {
@Autowired
GetFlights getFlights;
private MockWebServiceServer mockServer;
private static final String MESSAGES_NS =
"http://www.springframework.org/spring-ws/samples/airline/schemas/messages";
private static final String TYPES_NS = "http://www.springframework.org/spring-ws/samples/airline/schemas/types";
@Before
public void setUpMocks() throws Exception {
mockServer = MockWebServiceServer.createServer(getFlights);
}
@Test
public void getFlights() throws Exception {
Source getFlightsRequest = new StringSource(
"<GetFlightsRequest xmlns='" + MESSAGES_NS + "'>" + "<from>AMS</from>" + "<to>VCE</to>" +
"<departureDate>2006-01-31</departureDate>" + "</GetFlightsRequest>");
String flightInfo =
"<t:number>KL1653</t:number>" + "<t:departureTime>2006-01-31T10:05:00.000+01:00</t:departureTime>" +
"<t:from><t:code>AMS</t:code><t:name>Schiphol Airport</t:name><t:city>Amsterdam</t:city></t:from>" +
"<t:arrivalTime>2006-01-31T12:25:00.000+01:00</t:arrivalTime>" +
"<t:to><t:code>VCE</t:code><t:name>Marco Polo Airport</t:name><t:city>Venice</t:city></t:to>" +
"<t:serviceClass>economy</t:serviceClass>";
Source getFlightsResponse = new StringSource(
"<m:GetFlightsResponse xmlns:m='" + MESSAGES_NS + "' xmlns:t='" + TYPES_NS + "'>" + "<m:flight>" +
flightInfo + "</m:flight>" + "</m:GetFlightsResponse>");
mockServer.expect(payload(getFlightsRequest)).andRespond(withPayload(getFlightsResponse));
Source bookFlightResponse = new StringSource(
"<m:BookFlightResponse xmlns:m='" + MESSAGES_NS + "' xmlns:t='" + TYPES_NS + "'>" + "<t:id>4</t:id>" +
"<t:issueDate>2010-07-28</t:issueDate>" +
"<t:passengers><t:passenger><t:first>John</t:first><t:last>Doe</t:last></t:passenger></t:passengers>" +
"<t:flight>" + flightInfo + "</t:flight>" + "</m:BookFlightResponse>");
Map<String, String> namespaces = Collections.singletonMap("m", MESSAGES_NS);
mockServer.expect(xpath("/m:BookFlightRequest/m:flightNumber", namespaces).exists())
.andExpect(xpath("/m:BookFlightRequest/m:departureTime", namespaces).exists())
.andExpect(xpath("/m:BookFlightRequest/m:passengers", namespaces).exists())
.andRespond(withPayload(bookFlightResponse));
getFlights.getFlights();
mockServer.verify();
}
}

147
airline/server/build.gradle Normal file
View File

@@ -0,0 +1,147 @@
configurations {
jaxb
openjpa
}
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.gradle.api.plugins:gradle-tomcat-plugin:0.9.9'
}
}
ext.springVersion = '3.2.4.RELEASE'
ext.springWsVersion = '2.1.4.RELEASE'
ext.springSecVersion = '3.1.0.RELEASE'
ext.tomcatVersion = '7.0.42'
apply plugin: 'war'
apply plugin: 'tomcat'
task genJaxb {
ext.sourcesDir = "${buildDir}/generated-sources/jaxb"
ext.classesDir = "${buildDir}/classes/jaxb"
ext.schema = "${projectDir}/src/main/webapp/messages.xsd"
inputs.files schema
outputs.dir classesDir
doLast() {
project.ant {
taskdef name: "xjc", classname: "com.sun.tools.xjc.XJCTask",
classpath: configurations.jaxb.asPath
mkdir(dir: sourcesDir)
mkdir(dir: classesDir)
xjc(destdir: sourcesDir, schema: schema,
package: "org.springframework.ws.samples.airline.schema") {
produces(dir: sourcesDir, includes: "**/*.java")
}
javac(destdir: classesDir, source: 1.6, target: 1.6, debug: true,
debugLevel: "lines,vars,source",
classpath: configurations.jaxb.asPath) {
src(path: sourcesDir)
include(name: "**/*.java")
include(name: "*.java")
}
copy(todir: classesDir) {
fileset(dir: sourcesDir, erroronmissingdir: false) {
exclude(name: "**/*.java")
}
}
}
}
}
task enhance {
doLast {
ant.taskdef( name : 'openjpaenhancer',
classpath : project.runtimeClasspath.asPath,
classname : 'org.apache.openjpa.ant.PCEnhancerTask'
)
ant.openjpaenhancer(
classpath : project.runtimeClasspath.asPath)
ant.fileset(dir: "${projectDir}/src/main/java/") {
include(name: '**/domain/*.java')
exclude(name: 'ServiceClass.java')
}
}
}
war {
it.dependsOn enhance
}
test {
it.dependsOn enhance
}
tomcatRun {
it.dependsOn enhance
contextPath = 'airline-server'
}
dependencies {
compile(files(genJaxb.classesDir).builtBy(genJaxb))
// Spring-WS
compile("org.springframework.ws:spring-ws-core:$springWsVersion")
compile("org.springframework.ws:spring-ws-security:$springWsVersion") {
exclude group: 'com.sun.xml.wsit', module: 'wsit-rt'
exclude group: 'com.sun.xml.wsit', module: 'xws-security'
}
runtime("org.springframework.ws:spring-ws-support:$springWsVersion")
// Spring
runtime("org.springframework:spring-orm:$springVersion")
testCompile("org.springframework:spring-jdbc:$springVersion")
testCompile("org.springframework:spring-test:$springVersion")
// Spring Security
runtime("org.springframework.security:spring-security-core:$springSecVersion")
runtime("org.springframework.security:spring-security-config:$springSecVersion")
runtime("org.springframework.security:spring-security-web:$springSecVersion")
// JEE
runtime("javax.servlet:jstl:1.2")
// ORM
compile("org.apache.openjpa:openjpa:1.2.3")
runtime("commons-dbcp:commons-dbcp:1.2.1") {
exclude group: 'xml-apis', module: 'xml-apis'
exclude group: 'xerces', module: 'xerces'
}
runtime("hsqldb:hsqldb:1.8.0.7")
// Various
runtime("org.apache.activemq:activemq-core:4.1.2")
runtime("org.apache.derby:derby:10.3.1.4")
runtime("org.apache.ws.xmlschema:xmlschema-core:2.0.2")
runtime("com.sun.xml.wss:xws-security:3.0") {
exclude group: 'javax.xml.crypto', module: 'xmldsig'
}
runtime("joda-time:joda-time-jsptags:1.1.1")
runtime("log4j:log4j:1.2.16")
jaxb "com.sun.xml.bind:jaxb-xjc:2.1.7"
openjpa "org.apache.openjpa:openjpa:1.2.3"
tomcat("org.apache.tomcat.embed:tomcat-embed-core:$tomcatVersion",
"org.apache.tomcat.embed:tomcat-embed-logging-juli:$tomcatVersion")
tomcat("org.apache.tomcat.embed:tomcat-embed-jasper:$tomcatVersion") {
exclude group: 'org.eclipse.jdt.core.compiler', module: 'ecj'
}
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright 2005 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.dao;
import java.util.List;
import org.joda.time.DateTime;
import org.joda.time.Interval;
import org.springframework.dao.DataAccessException;
import org.springframework.ws.samples.airline.domain.Flight;
import org.springframework.ws.samples.airline.domain.ServiceClass;
public interface FlightDao {
List<Flight> findFlights(String fromAirportCode, String toAirportCode, Interval interval, ServiceClass serviceClass)
throws DataAccessException;
Flight getFlight(Long id);
Flight getFlight(String flightNumber, DateTime departureTime);
Flight update(Flight flight);
}

View File

@@ -0,0 +1,26 @@
/*
* Copyright 2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.dao;
import org.springframework.dao.DataAccessException;
import org.springframework.ws.samples.airline.domain.FrequentFlyer;
public interface FrequentFlyerDao {
FrequentFlyer get(String username) throws DataAccessException;
}

View File

@@ -0,0 +1,26 @@
/*
* Copyright 2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.dao;
import org.springframework.dao.DataAccessException;
import org.springframework.ws.samples.airline.domain.Ticket;
public interface TicketDao {
void save(Ticket ticket) throws DataAccessException;
}

View File

@@ -0,0 +1,108 @@
/*
* Copyright 2005-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.dao.jpa;
import javax.annotation.PostConstruct;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.ws.samples.airline.domain.Airport;
import org.springframework.ws.samples.airline.domain.Flight;
import org.springframework.ws.samples.airline.domain.FrequentFlyer;
import org.springframework.ws.samples.airline.domain.ServiceClass;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.joda.time.DateTime;
/**
* A simple class that uses JPA to initialize the database.
*
* @author Arjen Poutsma
* @since 1.5.0
*/
@Component
public class DatabaseInitializer {
private static final Log logger = LogFactory.getLog(DatabaseInitializer.class);
private final TransactionTemplate transactionTemplate;
@PersistenceContext
private EntityManager entityManager;
private Airport amsterdam;
private Airport venice;
@Autowired
public DatabaseInitializer(PlatformTransactionManager transactionManager) {
this.transactionTemplate = new TransactionTemplate(transactionManager);
}
@PostConstruct
public void initDatabase() {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
logger.info("Initializing Database");
createAirports();
createFlights();
createFrequentFlyers();
}
});
}
private void createAirports() {
amsterdam = new Airport("AMS", "Schiphol Airport", "Amsterdam");
entityManager.persist(amsterdam);
venice = new Airport("VCE", "Marco Polo Airport", "Venice");
entityManager.persist(venice);
}
private void createFlights() {
Flight flight = new Flight();
flight.setNumber("KL1653");
flight.setDepartureTime(new DateTime(2006, 1, 31, 10, 5, 0, 0));
flight.setFrom(amsterdam);
flight.setArrivalTime(new DateTime(2006, 1, 31, 12, 25, 0, 0));
flight.setTo(venice);
flight.setServiceClass(ServiceClass.ECONOMY);
flight.setSeatsAvailable(5);
flight.setMiles(200);
entityManager.persist(flight);
flight = new Flight();
flight.setNumber("KL1654");
flight.setDepartureTime(new DateTime(2006, 2, 5, 12, 40, 0, 0));
flight.setFrom(venice);
flight.setArrivalTime(new DateTime(2006, 2, 5, 14, 15, 0, 0));
flight.setTo(amsterdam);
flight.setServiceClass(ServiceClass.ECONOMY);
flight.setSeatsAvailable(5);
flight.setMiles(200);
entityManager.persist(flight);
}
private void createFrequentFlyers() {
entityManager.persist(new FrequentFlyer("John", "Doe", "john", "changeme"));
}
}

View File

@@ -0,0 +1,74 @@
/*
* Copyright 2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.dao.jpa;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.joda.time.DateTime;
import org.joda.time.Interval;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Repository;
import org.springframework.ws.samples.airline.dao.FlightDao;
import org.springframework.ws.samples.airline.domain.Flight;
import org.springframework.ws.samples.airline.domain.ServiceClass;
@Repository
public class JpaFlightDao implements FlightDao {
@PersistenceContext
private EntityManager entityManager;
public List<Flight> findFlights(String fromAirportCode,
String toAirportCode,
Interval interval,
ServiceClass serviceClass) throws DataAccessException {
Query query = entityManager.createQuery("SELECT f FROM Flight f WHERE f.from.code = :fromParam " +
"AND f.to.code = :toParam AND f.departureTime >= :start AND f.departureTime <= :end AND " +
"f.serviceClass = :class");
query.setParameter("fromParam", fromAirportCode);
query.setParameter("toParam", toAirportCode);
query.setParameter("start", interval.getStart());
query.setParameter("end", interval.getEnd());
query.setParameter("class", serviceClass);
return query.getResultList();
}
public Flight getFlight(Long id) {
return entityManager.find(Flight.class, id);
}
public Flight getFlight(String flightNumber, DateTime departureTime) {
Query query = entityManager
.createQuery("SELECT f FROM Flight f WHERE f.number = :number AND f.departureTime = :departureTime");
query.setParameter("number", flightNumber);
query.setParameter("departureTime", departureTime);
try {
return (Flight) query.getSingleResult();
}
catch (NoResultException e) {
return null;
}
}
public Flight update(Flight flight) {
return entityManager.merge(flight);
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright 2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.dao.jpa;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Repository;
import org.springframework.ws.samples.airline.dao.FrequentFlyerDao;
import org.springframework.ws.samples.airline.domain.FrequentFlyer;
@Repository
public class JpaFrequentFlyerDao implements FrequentFlyerDao {
@PersistenceContext
private EntityManager entityManager;
public FrequentFlyer get(String username) throws DataAccessException {
Query query = entityManager.createQuery("SELECT f FROM FrequentFlyer f WHERE f.username = :username");
query.setParameter("username", username);
try {
return (FrequentFlyer) query.getSingleResult();
}
catch (NoResultException e) {
return null;
}
}
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright 2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.dao.jpa;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Repository;
import org.springframework.ws.samples.airline.dao.TicketDao;
import org.springframework.ws.samples.airline.domain.Ticket;
@Repository
public class JpaTicketDao implements TicketDao {
@PersistenceContext
private EntityManager entityManager;
public void save(Ticket ticket) throws DataAccessException {
entityManager.persist(ticket);
}
}

View File

@@ -0,0 +1,74 @@
/*
* Copyright 2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.domain;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "AIRPORT")
public class Airport implements Serializable {
@Id
@Column(name = "CODE")
private String code;
@Column(name = "NAME")
private String name;
@Column(name = "CITY")
private String city;
public Airport() {
}
public Airport(String code, String name, String city) {
this.code = code;
this.name = name;
this.city = city;
}
public String getCity() {
return city;
}
public String getCode() {
return code;
}
public String getName() {
return name;
}
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof Airport)) {
return false;
}
final Airport that = (Airport) other;
return code.equals(that.code);
}
public int hashCode() {
return code.hashCode();
}
}

View File

@@ -0,0 +1,179 @@
/*
* Copyright 2005, 2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.domain;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.apache.openjpa.persistence.Persistent;
import org.joda.time.DateTime;
@Entity
@Table(name = "FLIGHT")
public class Flight implements Serializable {
@Id
@Column(name = "ID")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "NUMBER")
private String number;
@Column(name = "DEPARTURE_TIME")
@Persistent
private DateTime departureTime;
@ManyToOne
@JoinColumn(name = "FROM_AIRPORT_CODE", nullable = false)
private Airport from;
@Column(name = "ARRIVAL_TIME")
@Persistent
private DateTime arrivalTime;
@ManyToOne
@JoinColumn(name = "TO_AIRPORT_CODE", nullable = false)
private Airport to;
@Column(name = "SERVICE_CLASS")
@Enumerated(EnumType.STRING)
private ServiceClass serviceClass;
@Column(name = "SEATS_AVAILABLE")
private int seatsAvailable;
@Column(name = "MILES")
private int miles;
public Flight() {
}
public Flight(Long id) {
this.id = id;
}
public Long getId() {
return id;
}
public DateTime getArrivalTime() {
return arrivalTime;
}
public void setArrivalTime(DateTime arrivalTime) {
this.arrivalTime = arrivalTime;
}
public DateTime getDepartureTime() {
return departureTime;
}
public void setDepartureTime(DateTime departureTime) {
this.departureTime = departureTime;
}
public Airport getFrom() {
return from;
}
public void setFrom(Airport from) {
this.from = from;
}
public int getMiles() {
return miles;
}
public void setMiles(int miles) {
this.miles = miles;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public int getSeatsAvailable() {
return seatsAvailable;
}
public void setSeatsAvailable(int seatsAvailable) {
this.seatsAvailable = seatsAvailable;
}
public ServiceClass getServiceClass() {
return serviceClass;
}
public void setServiceClass(ServiceClass serviceClass) {
this.serviceClass = serviceClass;
}
public Airport getTo() {
return to;
}
public void setTo(Airport to) {
this.to = to;
}
public void substractSeats(int count) {
seatsAvailable -= count;
}
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final Flight flight = (Flight) o;
if (!departureTime.equals(flight.departureTime)) {
return false;
}
return number.equals(flight.number);
}
public int hashCode() {
int result = number.hashCode();
result = 29 * result + departureTime.hashCode();
return result;
}
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append(getNumber());
buffer.append(' ');
buffer.append(getDepartureTime().toString());
return buffer.toString();
}
}

View File

@@ -0,0 +1,97 @@
/*
* Copyright 2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.domain;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
@Entity
@Table(name = "FREQUENT_FLYER")
@PrimaryKeyJoinColumn(name = "PASSENGER_ID")
public class FrequentFlyer extends Passenger {
@Column(name = "USERNAME")
private String username;
@Column(name = "PASSWORD")
private String password;
@Column(name = "MILES")
private int miles;
public FrequentFlyer() {
}
public FrequentFlyer(String username) {
this.username = username;
}
public FrequentFlyer(String firstName, String lastName, String username, String password) {
super(firstName, lastName);
this.username = username;
this.password = password;
}
public int getMiles() {
return miles;
}
public void setMiles(int miles) {
this.miles = miles;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof FrequentFlyer)) {
return false;
}
final FrequentFlyer that = (FrequentFlyer) other;
return username.equals(that.username);
}
public int hashCode() {
return username.hashCode();
}
public String toString() {
return username;
}
public void addMiles(int miles) {
this.miles += miles;
}
}

View File

@@ -0,0 +1,99 @@
/*
* Copyright 2005, 2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.domain;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;
@Entity
@Table(name = "PASSENGER")
@Inheritance(strategy = InheritanceType.JOINED)
public class Passenger implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private Long id;
@Column(name = "FIRST_NAME")
private String firstName;
@Column(name = "LAST_NAME")
private String lastName;
public Passenger() {
}
public Passenger(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public Passenger(Long id, String firstName, String lastName) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public Long getId() {
return id;
}
public String getLastName() {
return lastName;
}
public String toString() {
return firstName + " " + lastName;
}
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final Passenger passenger = (Passenger) o;
if (!getFirstName().equals(passenger.getFirstName())) {
return false;
}
if (!getLastName().equals(passenger.getLastName())) {
return false;
}
return true;
}
public int hashCode() {
int result = getFirstName().hashCode();
result = 29 * result + getLastName().hashCode();
return result;
}
}

View File

@@ -0,0 +1,26 @@
/*
* Copyright 2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.domain;
public enum ServiceClass {
ECONOMY,
BUSINESS,
FIRST
}

View File

@@ -0,0 +1,97 @@
/*
* Copyright 2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.domain;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.apache.openjpa.persistence.Persistent;
import org.joda.time.LocalDate;
@Entity
@Table(name = "TICKET")
public class Ticket implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "ISSUE_DATE")
@Persistent
private LocalDate issueDate;
@ManyToOne
@JoinColumn(name = "FLIGHT_ID", nullable = false)
private Flight flight;
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinTable(name = "PASSENGER_TICKET",
joinColumns = @JoinColumn(name = "TICKET_ID"),
inverseJoinColumns = @JoinColumn(name = "PASSENGER_ID"))
private Set<Passenger> passengers = new HashSet<Passenger>();
public Ticket() {
}
public Ticket(Long id) {
this.id = id;
}
public Long getId() {
return id;
}
public Flight getFlight() {
return flight;
}
public void setFlight(Flight flight) {
this.flight = flight;
}
public LocalDate getIssueDate() {
return issueDate;
}
public void setIssueDate(LocalDate issueDate) {
this.issueDate = issueDate;
}
public Set<Passenger> getPassengers() {
return passengers;
}
public void setPassengers(Set<Passenger> passengers) {
this.passengers = passengers;
}
public void addPassenger(Passenger passenger) {
passengers.add(passenger);
}
}

View File

@@ -0,0 +1,57 @@
/*
* Copyright 2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.domain.openjpa;
import java.sql.Timestamp;
import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.meta.JavaSQLTypes;
import org.apache.openjpa.jdbc.meta.ValueMapping;
import org.apache.openjpa.jdbc.meta.strats.AbstractValueHandler;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.ColumnIO;
import org.joda.time.DateTime;
/**
* @author Arjen Poutsma
* @since 1.1.0
*/
public class DateTimeValueHandler extends AbstractValueHandler {
private static final DateTimeValueHandler instance = new DateTimeValueHandler();
public static DateTimeValueHandler getInstance() {
return instance;
}
public Column[] map(ValueMapping vm, String name, ColumnIO io, boolean adapt) {
Column col = new Column();
col.setName(name);
col.setJavaType(JavaSQLTypes.TIMESTAMP);
return new Column[]{col};
}
@Override
public Object toDataStoreValue(ValueMapping valueMapping, Object val, JDBCStore jdbcStore) {
return val == null ? null : new Timestamp(((DateTime) val).getMillis());
}
@Override
public Object toObjectValue(ValueMapping valueMapping, Object val) {
return val == null ? null : new DateTime(val);
}
}

View File

@@ -0,0 +1,51 @@
/*
* Copyright 2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.domain.openjpa;
import java.sql.Date;
import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.meta.JavaSQLTypes;
import org.apache.openjpa.jdbc.meta.ValueMapping;
import org.apache.openjpa.jdbc.meta.strats.AbstractValueHandler;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.ColumnIO;
import org.joda.time.LocalDate;
/**
* @author Arjen Poutsma
* @since 1.1.0
*/
public class LocalDateValueHandler extends AbstractValueHandler {
public Column[] map(ValueMapping vm, String name, ColumnIO io, boolean adapt) {
Column col = new Column();
col.setName(name);
col.setJavaType(JavaSQLTypes.DATE);
return new Column[]{col};
}
@Override
public Object toDataStoreValue(ValueMapping valueMapping, Object val, JDBCStore jdbcStore) {
return val == null ? null : new Date(((LocalDate) val).toDateMidnight().getMillis());
}
@Override
public Object toObjectValue(ValueMapping valueMapping, Object val) {
return val == null ? null : new LocalDate(val);
}
}

View File

@@ -0,0 +1,147 @@
/*
* Copyright 2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.schema.support;
import java.util.ArrayList;
import java.util.List;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeConstants;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.LocalDate;
import org.springframework.ws.samples.airline.domain.Passenger;
import org.springframework.ws.samples.airline.schema.Airport;
import org.springframework.ws.samples.airline.schema.Flight;
import org.springframework.ws.samples.airline.schema.Name;
import org.springframework.ws.samples.airline.schema.ServiceClass;
import org.springframework.ws.samples.airline.schema.Ticket;
/** @author Arjen Poutsma */
public abstract class SchemaConversionUtils {
private SchemaConversionUtils() {
}
public static Flight toSchemaType(org.springframework.ws.samples.airline.domain.Flight domainFlight)
throws DatatypeConfigurationException {
Flight schemaFlight = new Flight();
schemaFlight.setNumber(domainFlight.getNumber());
schemaFlight.setDepartureTime(toXMLGregorianCalendar(domainFlight.getDepartureTime()));
schemaFlight.setFrom(toSchemaType(domainFlight.getFrom()));
schemaFlight.setArrivalTime(toXMLGregorianCalendar(domainFlight.getArrivalTime()));
schemaFlight.setTo(toSchemaType(domainFlight.getTo()));
schemaFlight.setServiceClass(toSchemaType(domainFlight.getServiceClass()));
return schemaFlight;
}
public static List<Flight> toSchemaType(List<org.springframework.ws.samples.airline.domain.Flight> domainFlights)
throws DatatypeConfigurationException {
List<Flight> schemaFlights = new ArrayList<Flight>(domainFlights.size());
for (org.springframework.ws.samples.airline.domain.Flight domainFlight : domainFlights) {
schemaFlights.add(toSchemaType(domainFlight));
}
return schemaFlights;
}
public static XMLGregorianCalendar toXMLGregorianCalendar(DateTime dateTime) throws DatatypeConfigurationException {
DatatypeFactory factory = DatatypeFactory.newInstance();
return factory.newXMLGregorianCalendar(dateTime.toGregorianCalendar());
}
public static DateTime toDateTime(XMLGregorianCalendar calendar) {
int timeZoneMinutes = calendar.getTimezone();
DateTimeZone timeZone = DateTimeZone.forOffsetHoursMinutes(timeZoneMinutes / 60, timeZoneMinutes % 60);
return new DateTime(calendar.getYear(), calendar.getMonth(), calendar.getDay(), calendar.getHour(),
calendar.getMinute(), calendar.getSecond(), calendar.getMillisecond(), timeZone);
}
public static XMLGregorianCalendar toXMLGregorianCalendar(LocalDate localDate)
throws DatatypeConfigurationException {
DatatypeFactory factory = DatatypeFactory.newInstance();
return factory.newXMLGregorianCalendarDate(localDate.getYear(), localDate.getMonthOfYear(),
localDate.getDayOfMonth(), DatatypeConstants.FIELD_UNDEFINED);
}
public static LocalDate toLocalDate(XMLGregorianCalendar calendar) {
return new LocalDate(calendar.getYear(), calendar.getMonth(), calendar.getDay());
}
public static Airport toSchemaType(org.springframework.ws.samples.airline.domain.Airport domainAirport) {
if (domainAirport == null) {
return null;
}
Airport schemaAirport = new Airport();
schemaAirport.setCode(domainAirport.getCode());
schemaAirport.setName(domainAirport.getName());
schemaAirport.setCity(domainAirport.getCity());
return schemaAirport;
}
public static ServiceClass toSchemaType(org.springframework.ws.samples.airline.domain.ServiceClass domainServiceClass) {
switch (domainServiceClass) {
case BUSINESS:
return ServiceClass.BUSINESS;
case ECONOMY:
return ServiceClass.ECONOMY;
case FIRST:
return ServiceClass.FIRST;
default:
throw new IllegalArgumentException("Invalid domain service class: [" + domainServiceClass + "]");
}
}
public static org.springframework.ws.samples.airline.domain.ServiceClass toDomainType(ServiceClass schemaServiceClass) {
if (schemaServiceClass == null) {
return null;
}
switch (schemaServiceClass) {
case BUSINESS:
return org.springframework.ws.samples.airline.domain.ServiceClass.BUSINESS;
case ECONOMY:
return org.springframework.ws.samples.airline.domain.ServiceClass.ECONOMY;
case FIRST:
return org.springframework.ws.samples.airline.domain.ServiceClass.FIRST;
default:
throw new IllegalArgumentException("Invalid schema service class: [" + schemaServiceClass + "]");
}
}
public static Name toSchemaType(org.springframework.ws.samples.airline.domain.Passenger passenger) {
Name name = new Name();
name.setFirst(passenger.getFirstName());
name.setLast(passenger.getLastName());
return name;
}
public static Ticket toSchemaType(org.springframework.ws.samples.airline.domain.Ticket domainTicket)
throws DatatypeConfigurationException {
Ticket schemaTicket = new Ticket();
schemaTicket.setId(domainTicket.getId());
schemaTicket.setFlight(toSchemaType(domainTicket.getFlight()));
schemaTicket.setIssueDate(toXMLGregorianCalendar(domainTicket.getIssueDate()));
if (!domainTicket.getPassengers().isEmpty()) {
schemaTicket.setPassengers(new Ticket.Passengers());
}
for (Passenger passenger : domainTicket.getPassengers()) {
schemaTicket.getPassengers().getPassenger().add(toSchemaType(passenger));
}
return schemaTicket;
}
}

View File

@@ -0,0 +1,82 @@
/*
* Copyright 2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.security;
import java.util.ArrayList;
import java.util.Collection;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.ws.samples.airline.domain.FrequentFlyer;
/**
* A wrapper around an <code>FrequentFlyer</code> which provides extra functionality needed to implement the
* <code>UserDetails</code> interface.
*
* @author Arjen Poutsma
*/
public class FrequentFlyerDetails implements UserDetails {
private FrequentFlyer frequentFlyer;
public static final Collection<GrantedAuthority> GRANTED_AUTHORITIES =
new ArrayList<GrantedAuthority>();
{
GRANTED_AUTHORITIES.add(new GrantedAuthorityImpl("ROLE_FREQUENT_FLYER"));
};
public FrequentFlyerDetails(FrequentFlyer frequentFlyer) {
this.frequentFlyer = frequentFlyer;
}
public Collection<GrantedAuthority> getAuthorities() {
return GRANTED_AUTHORITIES;
}
public String getPassword() {
return frequentFlyer.getPassword();
}
public String getUsername() {
return frequentFlyer.getUsername();
}
public boolean isAccountNonExpired() {
return true;
}
public boolean isAccountNonLocked() {
return true;
}
public boolean isCredentialsNonExpired() {
return true;
}
public boolean isEnabled() {
return true;
}
public FrequentFlyer getFrequentFlyer() {
return frequentFlyer;
}
public String toString() {
return frequentFlyer.toString();
}
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright 2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.security;
import org.springframework.ws.samples.airline.domain.FrequentFlyer;
import org.springframework.ws.samples.airline.service.NoSuchFrequentFlyerException;
/**
* Defines the business logic for handling frequent flyers.
*
* @author Arjen Poutsma
*/
public interface FrequentFlyerSecurityService {
/**
* Returns the <code>FrequentFlyer</code> with the given username.
*
* @param username the username
* @return the frequent flyer with the given username, or <code>null</code> if not found
* @throws NoSuchFrequentFlyerException when the frequent flyer cannot be found
*/
FrequentFlyer getFrequentFlyer(String username) throws NoSuchFrequentFlyerException;
/**
* Returns the <code>FrequentFlyer</code> that is currently logged in.
*
* @return the frequent flyer that is currently logged in, or <code>null</code> if not found
*/
FrequentFlyer getCurrentlyAuthenticatedFrequentFlyer();
}

View File

@@ -0,0 +1,86 @@
/*
* Copyright 2005-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ws.samples.airline.dao.FrequentFlyerDao;
import org.springframework.ws.samples.airline.domain.FrequentFlyer;
import org.springframework.ws.samples.airline.service.NoSuchFrequentFlyerException;
/**
* Implementation of the <code>FrequentFlyerSecurityService</code> that uses Spring Security.
*
* @author Arjen Poutsma
*/
public class SpringFrequentFlyerSecurityService implements FrequentFlyerSecurityService, UserDetailsService {
private FrequentFlyerDao frequentFlyerDao;
@Autowired
public SpringFrequentFlyerSecurityService(FrequentFlyerDao frequentFlyerDao) {
this.frequentFlyerDao = frequentFlyerDao;
}
@Transactional
public FrequentFlyer getCurrentlyAuthenticatedFrequentFlyer() {
SecurityContext context = SecurityContextHolder.getContext();
Authentication authentication = context.getAuthentication();
if (authentication != null) {
if (authentication.getPrincipal() instanceof FrequentFlyerDetails) {
FrequentFlyerDetails details = (FrequentFlyerDetails) authentication.getPrincipal();
return details.getFrequentFlyer();
}
else {
return (FrequentFlyer) authentication.getPrincipal();
}
}
else {
return null;
}
}
@Transactional
public FrequentFlyer getFrequentFlyer(String username) throws NoSuchFrequentFlyerException {
FrequentFlyer frequentFlyer = frequentFlyerDao.get(username);
if (frequentFlyer != null) {
return frequentFlyer;
}
else {
throw new NoSuchFrequentFlyerException(username);
}
}
@Transactional
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
FrequentFlyer frequentFlyer = frequentFlyerDao.get(username);
if (frequentFlyer != null) {
return new FrequentFlyerDetails(frequentFlyer);
}
else {
throw new UsernameNotFoundException("Frequent flyer '" + username + "' not found");
}
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright 2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.security;
import org.springframework.ws.samples.airline.domain.FrequentFlyer;
import org.springframework.ws.samples.airline.service.NoSuchFrequentFlyerException;
/**
* Stub implementation of <code>FrequentFlyerSecurityService</code>. This implementation is used by default by {@link
* org.springframework.ws.samples.airline.service.impl.AirlineServiceImpl}, to allow it to run without depending on
* Spring Security.
*
* @author Arjen Poutsma
*/
public class StubFrequentFlyerSecurityService implements FrequentFlyerSecurityService {
private FrequentFlyer john;
public StubFrequentFlyerSecurityService() {
john = new FrequentFlyer("John", "Doe", "john", "changeme");
john.setMiles(10);
}
public FrequentFlyer getFrequentFlyer(String username) throws NoSuchFrequentFlyerException {
if (john.getUsername().equals(username)) {
return john;
}
else {
throw new NoSuchFrequentFlyerException(username);
}
}
public FrequentFlyer getCurrentlyAuthenticatedFrequentFlyer() {
return john;
}
}

View File

@@ -0,0 +1,84 @@
/*
* Copyright 2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.service;
import java.util.List;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.springframework.ws.samples.airline.domain.Flight;
import org.springframework.ws.samples.airline.domain.FrequentFlyer;
import org.springframework.ws.samples.airline.domain.Passenger;
import org.springframework.ws.samples.airline.domain.ServiceClass;
import org.springframework.ws.samples.airline.domain.Ticket;
/**
* Defines the business logic of the Airline application.
*
* @author Arjen Poutsma
*/
public interface AirlineService {
/**
* Returns a single <code>Flight</code> with the given id.
*
* @param id the flight identifier
* @return the flight
* @throws NoSuchFlightException if a flight with the specified flight iddoes not exist
*/
Flight getFlight(Long id) throws NoSuchFlightException;
/**
* Returns a list of <code>Flight</code> objects that fall within the specified criteria.
*
* @param fromAirportCode the three-letter airport code to get flights from
* @param toAirportCode the three-letter airport code to get flights to
* @param departureDate the date of the flights
* @param serviceClass the desired service class level. May be <code>null</code>
* @return a list of flights
*/
List<Flight> getFlights(String fromAirportCode,
String toAirportCode,
LocalDate departureDate,
ServiceClass serviceClass);
/**
* Books a single flight for a number of passengers. Passengers can be either specified by name or by frequent flyer
* username. If a {@link FrequentFlyer} is specified, the first and last name are looked up in the database.
*
* @param flightNumber the number of the flight to book
* @param departureTime the departure time of the flight to book
* @param passengers the list of passengers for the flight to book. Can be either {@link Passenger} objects with
* a first and last name, or {@link FrequentFlyer} objects with a username.
* @return the created ticket
* @throws NoSuchFlightException if a flight with the specified flight number and departure time does not
* exist
* @throws NoSeatAvailableException if not enough seats are available for the flight
* @throws NoSuchFrequentFlyerException if a specified {@link FrequentFlyer} cannot be found
* @see org.springframework.ws.samples.airline.domain.Passenger
* @see org.springframework.ws.samples.airline.domain.FrequentFlyer
*/
Ticket bookFlight(String flightNumber, DateTime departureTime, List<Passenger> passengers)
throws NoSuchFlightException, NoSeatAvailableException, NoSuchFrequentFlyerException;
/**
* Returns the amount of frequent flyer award miles for the currently logged in frequent flyer.
*
* @return the amount of frequent flyer miles
*/
int getFrequentFlyerMileage();
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright 2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.service;
import org.springframework.ws.samples.airline.domain.Flight;
import org.springframework.ws.soap.server.endpoint.annotation.FaultCode;
import org.springframework.ws.soap.server.endpoint.annotation.SoapFault;
/**
* Exception thrown when not enough seats are available for a flight.
*
* @author Arjen Poutsma
*/
@SoapFault(faultCode = FaultCode.SERVER)
public class NoSeatAvailableException extends Exception {
private Flight flight;
public NoSeatAvailableException(Flight flight) {
super("Flight [" + flight + "] has not more seats available");
this.flight = flight;
}
public Flight getFlight() {
return flight;
}
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright 2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.service;
import org.joda.time.DateTime;
import org.springframework.ws.soap.server.endpoint.annotation.FaultCode;
import org.springframework.ws.soap.server.endpoint.annotation.SoapFault;
/**
* Exception thrown when a specified flight cannot be found.
*
* @author Arjen Poutsma
*/
@SoapFault(faultCode = FaultCode.CLIENT)
public class NoSuchFlightException extends Exception {
private String flightNumber;
private DateTime departureTime;
public NoSuchFlightException(String flightNumber, DateTime departureTime) {
super("No flight with number [" + flightNumber + "] and departure time [" + departureTime + "]");
this.flightNumber = flightNumber;
this.departureTime = departureTime;
}
public NoSuchFlightException(Long id) {
super("No flight with id [" + id + "]");
}
public String getFlightNumber() {
return flightNumber;
}
public DateTime getDepartureTime() {
return departureTime;
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright 2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.service;
import org.springframework.ws.soap.server.endpoint.annotation.FaultCode;
import org.springframework.ws.soap.server.endpoint.annotation.SoapFault;
/**
* Exception thrown when a specified frequent flyer cannot be found.
*
* @author Rossen Stoyanchev
* @author Arjen Poutsma
*/
@SoapFault(faultCode = FaultCode.CLIENT)
public class NoSuchFrequentFlyerException extends Exception {
private String username;
public NoSuchFrequentFlyerException(String username) {
super("No frequent flyer with name [" + username + "]");
this.username = username;
}
public String getusername() {
return username;
}
}

View File

@@ -0,0 +1,146 @@
/*
* Copyright 2005-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.ws.samples.airline.dao.FlightDao;
import org.springframework.ws.samples.airline.dao.TicketDao;
import org.springframework.ws.samples.airline.domain.Flight;
import org.springframework.ws.samples.airline.domain.FrequentFlyer;
import org.springframework.ws.samples.airline.domain.Passenger;
import org.springframework.ws.samples.airline.domain.ServiceClass;
import org.springframework.ws.samples.airline.domain.Ticket;
import org.springframework.ws.samples.airline.security.FrequentFlyerSecurityService;
import org.springframework.ws.samples.airline.security.StubFrequentFlyerSecurityService;
import org.springframework.ws.samples.airline.service.AirlineService;
import org.springframework.ws.samples.airline.service.NoSeatAvailableException;
import org.springframework.ws.samples.airline.service.NoSuchFlightException;
import org.springframework.ws.samples.airline.service.NoSuchFrequentFlyerException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
/**
* Default implementation of the <code>AirlineService</code> interface.
*
* @author Arjen Poutsma
*/
@Service
@Transactional(readOnly = true)
public class AirlineServiceImpl implements AirlineService {
private static final Log logger = LogFactory.getLog(AirlineServiceImpl.class);
private FlightDao flightDao;
private TicketDao ticketDao;
private FrequentFlyerSecurityService frequentFlyerSecurityService = new StubFrequentFlyerSecurityService();
@Autowired
public AirlineServiceImpl(FlightDao flightDao, TicketDao ticketDao) {
this.flightDao = flightDao;
this.ticketDao = ticketDao;
}
@Autowired(required = false)
public void setFrequentFlyerSecurityService(FrequentFlyerSecurityService frequentFlyerSecurityService) {
this.frequentFlyerSecurityService = frequentFlyerSecurityService;
}
@Transactional(readOnly = false,
rollbackFor = {NoSuchFlightException.class, NoSeatAvailableException.class, NoSuchFrequentFlyerException.class})
public Ticket bookFlight(String flightNumber, DateTime departureTime, List<Passenger> passengers)
throws NoSuchFlightException, NoSeatAvailableException, NoSuchFrequentFlyerException {
Assert.notEmpty(passengers, "No passengers given");
if (logger.isDebugEnabled()) {
logger.debug("Booking flight '" + flightNumber + "' on '" + departureTime + "' for " + passengers);
}
Flight flight = flightDao.getFlight(flightNumber, departureTime);
if (flight == null) {
throw new NoSuchFlightException(flightNumber, departureTime);
}
else if (flight.getSeatsAvailable() < passengers.size()) {
throw new NoSeatAvailableException(flight);
}
Ticket ticket = new Ticket();
ticket.setIssueDate(new LocalDate());
ticket.setFlight(flight);
for (Passenger passenger : passengers) {
// frequent flyer service is not required
if (passenger instanceof FrequentFlyer && frequentFlyerSecurityService != null) {
String username = ((FrequentFlyer) passenger).getUsername();
Assert.hasLength(username, "No username specified");
FrequentFlyer frequentFlyer = frequentFlyerSecurityService.getFrequentFlyer(username);
frequentFlyer.addMiles(flight.getMiles());
ticket.addPassenger(frequentFlyer);
}
else {
ticket.addPassenger(passenger);
}
}
flight.substractSeats(passengers.size());
flightDao.update(flight);
ticketDao.save(ticket);
return ticket;
}
public Flight getFlight(Long id) throws NoSuchFlightException {
Flight flight = flightDao.getFlight(id);
if (flight != null) {
return flight;
}
else {
throw new NoSuchFlightException(id);
}
}
public List<Flight> getFlights(String fromAirportCode,
String toAirportCode,
LocalDate departureDate,
ServiceClass serviceClass) {
if (serviceClass == null) {
serviceClass = ServiceClass.ECONOMY;
}
if (logger.isDebugEnabled()) {
logger.debug(
"Getting flights from '" + fromAirportCode + "' to '" + toAirportCode + "' on " + departureDate);
}
List<Flight> flights =
flightDao.findFlights(fromAirportCode, toAirportCode, departureDate.toInterval(), serviceClass);
if (logger.isDebugEnabled()) {
logger.debug("Returning " + flights.size() + " flights");
}
return flights;
}
@Secured({"ROLE_FREQUENT_FLYER"})
public int getFrequentFlyerMileage() {
if (logger.isDebugEnabled()) {
logger.debug("Using " + frequentFlyerSecurityService + " for security");
}
FrequentFlyer frequentFlyer = frequentFlyerSecurityService.getCurrentlyAuthenticatedFrequentFlyer();
return frequentFlyer != null ? frequentFlyer.getMiles() : 0;
}
}

View File

@@ -0,0 +1,80 @@
/*
* Copyright 2005-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.web;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.ws.samples.airline.domain.Flight;
import org.springframework.ws.samples.airline.domain.ServiceClass;
import org.springframework.ws.samples.airline.service.AirlineService;
import org.springframework.ws.samples.airline.service.NoSuchFlightException;
import org.joda.time.LocalDate;
/** @author Arjen Poutsma */
@Controller
@RequestMapping("/flights")
public class FlightsController {
private AirlineService airlineService;
@Autowired
public FlightsController(AirlineService airlineService) {
Assert.notNull(airlineService, "'airlineService' must not be null");
this.airlineService = airlineService;
}
@RequestMapping
public String flightList(@RequestParam(value = "from", required = false)String fromAirportCode,
@RequestParam(value = "to", required = false)String toAirportCode,
@RequestParam(value = "departureDate", required = false)String departureDateString,
@RequestParam(value = "serviceClass", required = false)String serviceClassString,
ModelMap model) {
if (!StringUtils.hasLength(departureDateString)) {
departureDateString = new LocalDate().toString();
}
if (!StringUtils.hasLength(serviceClassString)) {
serviceClassString = "ECONOMY";
}
ServiceClass serviceClass = ServiceClass.valueOf(serviceClassString);
LocalDate departureDate = new LocalDate(departureDateString);
if (StringUtils.hasLength(fromAirportCode) && StringUtils.hasLength(toAirportCode)) {
model.addAttribute("from", fromAirportCode);
model.addAttribute("to", toAirportCode);
model.addAttribute("departureDate", departureDateString);
model.addAttribute("serviceClass", serviceClassString);
model.addAttribute("flights",
airlineService.getFlights(fromAirportCode, toAirportCode, departureDate, serviceClass));
}
return "flights";
}
@RequestMapping(value = "{id}")
public String singleFlight(@PathVariable("id") long id, ModelMap model) throws NoSuchFlightException {
Flight flight = airlineService.getFlight(id);
model.addAttribute(flight);
return "flight";
}
}

View File

@@ -0,0 +1,179 @@
/*
* Copyright 2005-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.ws;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.xml.bind.JAXBElement;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.ws.samples.airline.domain.FrequentFlyer;
import org.springframework.ws.samples.airline.domain.Passenger;
import org.springframework.ws.samples.airline.domain.ServiceClass;
import org.springframework.ws.samples.airline.schema.BookFlightRequest;
import org.springframework.ws.samples.airline.schema.GetFlightsResponse;
import org.springframework.ws.samples.airline.schema.Name;
import org.springframework.ws.samples.airline.schema.ObjectFactory;
import org.springframework.ws.samples.airline.schema.Ticket;
import org.springframework.ws.samples.airline.schema.support.SchemaConversionUtils;
import org.springframework.ws.samples.airline.service.AirlineService;
import org.springframework.ws.samples.airline.service.NoSeatAvailableException;
import org.springframework.ws.samples.airline.service.NoSuchFlightException;
import org.springframework.ws.samples.airline.service.NoSuchFrequentFlyerException;
import org.springframework.ws.server.endpoint.annotation.Endpoint;
import org.springframework.ws.server.endpoint.annotation.Namespace;
import org.springframework.ws.server.endpoint.annotation.PayloadRoot;
import org.springframework.ws.server.endpoint.annotation.RequestPayload;
import org.springframework.ws.server.endpoint.annotation.ResponsePayload;
import org.springframework.ws.server.endpoint.annotation.XPathParam;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import static org.springframework.ws.samples.airline.ws.AirlineWebServiceConstants.*;
/**
* Endpoint that handles the Airline Web Service messages using a combination of JAXB2 marshalling and XPath
* expressions.
*
* @author Arjen Poutsma
*/
@Endpoint
public class AirlineEndpoint {
private static final Log logger = LogFactory.getLog(AirlineEndpoint.class);
private final ObjectFactory objectFactory = new ObjectFactory();
private final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
private final AirlineService airlineService;
@Autowired
public AirlineEndpoint(AirlineService airlineService) {
this.airlineService = airlineService;
}
/**
* This endpoint method uses a combination of XPath expressions and marshalling to handle message with a
* <code>&lt;GetFlightsRequest&gt;</code> payload.
*
* @param from the from airport
* @param to the to airport
* @param departureDateString the string representation of the departure date
* @param serviceClassString the string representation of the service class
* @return the JAXB2 representation of a <code>&lt;GetFlightsResponse&gt;</code>
*/
@PayloadRoot(localPart = GET_FLIGHTS_REQUEST, namespace = MESSAGES_NAMESPACE)
@Namespace(prefix = "m", uri = MESSAGES_NAMESPACE)
@ResponsePayload
public GetFlightsResponse getFlights(@XPathParam("//m:from") String from,
@XPathParam("//m:to") String to,
@XPathParam("//m:departureDate") String departureDateString,
@XPathParam("//m:serviceClass") String serviceClassString)
throws DatatypeConfigurationException {
if (logger.isDebugEnabled()) {
logger.debug("Received GetFlightsRequest '" + from + "' to '" + to + "' on " + departureDateString);
}
LocalDate departureDate = new LocalDate(departureDateString);
ServiceClass serviceClass = null;
if (StringUtils.hasLength(serviceClassString)) {
serviceClass = ServiceClass.valueOf(serviceClassString.toUpperCase());
}
List<org.springframework.ws.samples.airline.domain.Flight> flights =
airlineService.getFlights(from, to, departureDate, serviceClass);
GetFlightsResponse response = objectFactory.createGetFlightsResponse();
for (org.springframework.ws.samples.airline.domain.Flight domainFlight : flights) {
response.getFlight().add(SchemaConversionUtils.toSchemaType(domainFlight));
}
return response;
}
/**
* This endpoint method uses marshalling to handle message with a <code>&lt;BookFlightRequest&gt;</code> payload.
*
* @param request the JAXB2 representation of a <code>&lt;BookFlightRequest&gt;</code>
* @return the JAXB2 representation of a <code>&lt;BookFlightResponse&gt;</code>
*/
@PayloadRoot(localPart = BOOK_FLIGHT_REQUEST, namespace = MESSAGES_NAMESPACE)
@ResponsePayload
public JAXBElement<Ticket> bookFlight(@RequestPayload BookFlightRequest request)
throws NoSeatAvailableException, DatatypeConfigurationException, NoSuchFlightException,
NoSuchFrequentFlyerException {
if (logger.isDebugEnabled()) {
logger.debug("Received BookingFlightRequest '" + request.getFlightNumber() + "' on '" +
request.getDepartureTime() + "' for " + request.getPassengers().getPassengerOrUsername());
}
Ticket ticket = bookSchemaFlight(request.getFlightNumber(), request.getDepartureTime(),
request.getPassengers().getPassengerOrUsername());
return objectFactory.createBookFlightResponse(ticket);
}
/**
* Converts between the domain and schema types.
*/
private Ticket bookSchemaFlight(String flightNumber,
XMLGregorianCalendar xmlDepartureTime,
List<Object> passengerOrUsernameList)
throws NoSeatAvailableException, NoSuchFlightException, NoSuchFrequentFlyerException,
DatatypeConfigurationException {
DateTime departureTime = SchemaConversionUtils.toDateTime(xmlDepartureTime);
List<Passenger> passengers = new ArrayList<Passenger>(passengerOrUsernameList.size());
for (Iterator<Object> iterator = passengerOrUsernameList.iterator(); iterator.hasNext();) {
Object passengerOrUsername = iterator.next();
if (passengerOrUsername instanceof Name) {
Name passengerName = (Name) passengerOrUsername;
Passenger passenger = new Passenger(passengerName.getFirst(), passengerName.getLast());
passengers.add(passenger);
}
else if (passengerOrUsername instanceof String) {
String frequentFlyerUsername = (String) passengerOrUsername;
FrequentFlyer frequentFlyer = new FrequentFlyer(frequentFlyerUsername);
passengers.add(frequentFlyer);
}
}
org.springframework.ws.samples.airline.domain.Ticket domainTicket =
airlineService.bookFlight(flightNumber, departureTime, passengers);
return SchemaConversionUtils.toSchemaType(domainTicket);
}
@PayloadRoot(localPart = GET_FREQUENT_FLYER_MILEAGE_REQUEST, namespace = MESSAGES_NAMESPACE)
@ResponsePayload
public Element getFrequentFlyerMileage() throws Exception {
if (logger.isDebugEnabled()) {
logger.debug("Received GetFrequentFlyerMileageRequest");
}
int mileage = airlineService.getFrequentFlyerMileage();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = documentBuilder.newDocument();
Element response = document.createElementNS(MESSAGES_NAMESPACE, GET_FREQUENT_FLYER_MILEAGE_RESPONSE);
response.setTextContent(Integer.toString(mileage));
return response;
}
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.ws;
/** @author Arjen Poutsma */
public interface AirlineWebServiceConstants {
String BOOK_FLIGHT_REQUEST = "BookFlightRequest";
String GET_FLIGHTS_REQUEST = "GetFlightsRequest";
String GET_FREQUENT_FLYER_MILEAGE_RESPONSE = "GetFrequentFlyerMileageResponse";
String MESSAGES_NAMESPACE = "http://www.springframework.org/spring-ws/samples/airline/schemas/messages";
String GET_FREQUENT_FLYER_MILEAGE_REQUEST = "GetFrequentFlyerMileageRequest";
}

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="airline">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<class>org.springframework.ws.samples.airline.domain.Airport</class>
<class>org.springframework.ws.samples.airline.domain.Flight</class>
<class>org.springframework.ws.samples.airline.domain.FrequentFlyer</class>
<class>org.springframework.ws.samples.airline.domain.Passenger</class>
<class>org.springframework.ws.samples.airline.domain.Ticket</class>
</persistence-unit>
</persistence>

View File

@@ -0,0 +1,8 @@
log4j.rootLogger=WARN, stdout
log4j.logger.org.springframework.ws=DEBUG
log4j.logger.org.springframework.xml=DEBUG
log4j.logger.openjpa=INFO
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<context:component-scan base-package="org.springframework.ws.samples.airline.dao.jpa"/>
<context:annotation-config/>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="airline"/>
<property name="dataSource" ref="dataSource"/>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.OpenJpaDialect"/>
</property>
<property name="jpaProperties">
<props>
<prop key="openjpa.Log">commons</prop>
<prop key="openjpa.jdbc.SynchronizeMappings">buildSchema</prop>
<prop key="openjpa.jdbc.MappingDefaults">
FieldStrategies='org.joda.time.DateTime=org.springframework.ws.samples.airline.domain.openjpa.DateTimeValueHandler,
org.joda.time.LocalDate=org.springframework.ws.samples.airline.domain.openjpa.LocalDateValueHandler'
</prop>
<prop key="openjpa.jdbc.DBDictionary">org.apache.openjpa.jdbc.sql.HSQLDictionary</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
<property name="url" value="jdbc:hsqldb:mem:airline"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
</bean>
</beans>

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:jms="http://www.springframework.org/schema/jms"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-3.1.xsd">
<!-- ===================== JMS TRANSPORT ===================================== -->
<bean id="broker" class="org.apache.activemq.broker.BrokerFactory" factory-method="createBroker"
init-method="start">
<constructor-arg value="broker:tcp://localhost:61616?persistent=false"/>
</bean>
<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://localhost:61616"/>
</bean>
<jms:listener-container connection-factory="connectionFactory">
<jms:listener destination="RequestQueue" ref="messageListener"/>
</jms:listener-container>
<bean id="messageListener" class="org.springframework.ws.transport.jms.WebServiceMessageListener">
<property name="messageFactory" ref="messageFactory"/>
<property name="messageReceiver" ref="messageReceiver"/>
</bean>
</beans>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<description>
This application context contains the WS-Security and Spring Security beans.
</description>
<security:global-method-security secured-annotations="enabled"/>
<security:authentication-manager>
<security:authentication-provider user-service-ref="securityService"/>
</security:authentication-manager>
<bean id="securityService"
class="org.springframework.ws.samples.airline.security.SpringFrequentFlyerSecurityService">
<description>
A security service used to obtain Frequent Flyer information.
</description>
</bean>
</beans>

View File

@@ -0,0 +1,3 @@
<xwss:SecurityConfiguration dumpMessages="false" xmlns:xwss="http://java.sun.com/xml/ns/xwss/config">
<xwss:RequireUsernameToken passwordDigestRequired="true" nonceRequired="true"/>
</xwss:SecurityConfiguration>

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<tx:annotation-driven/>
<context:annotation-config/>
<context:component-scan base-package="org.springframework.ws.samples.airline.service"/>
</beans>

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:sws="http://www.springframework.org/schema/web-services"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/web-services http://www.springframework.org/schema/web-services/web-services-2.0.xsd">
<sws:annotation-driven />
<sws:interceptors>
<bean class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor"/>
<bean class="org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor">
<property name="xsdSchemaCollection" ref="schemaCollection"/>
<property name="validateRequest" value="true"/>
<property name="validateResponse" value="true"/>
</bean>
<sws:payloadRoot localPart="GetFrequentFlyerMileageRequest" namespaceUri="http://www.springframework.org/spring-ws/samples/airline/schemas/messages">
<bean class="org.springframework.ws.soap.security.xwss.XwsSecurityInterceptor">
<property name="secureResponse" value="false"/>
<property name="policyConfiguration"
value="classpath:org/springframework/ws/samples/airline/security/securityPolicy.xml"/>
<property name="callbackHandler">
<bean class="org.springframework.ws.soap.security.xwss.callback.SpringDigestPasswordValidationCallbackHandler">
<property name="userDetailsService" ref="securityService"/>
</bean>
</property>
</bean>
</sws:payloadRoot>
</sws:interceptors>
<context:component-scan base-package="org.springframework.ws.samples.airline.ws"/>
<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory"/>
<bean id="messageReceiver" class="org.springframework.ws.soap.server.SoapMessageDispatcher"/>
<bean id="schemaCollection" class="org.springframework.xml.xsd.commons.CommonsXsdSchemaCollection">
<description>
This bean wrap the messages.xsd (which imports types.xsd), and inlines them as a one.
</description>
<property name="xsds" value="/messages.xsd"/>
<property name="inline" value="true"/>
</bean>
</beans>

View File

@@ -0,0 +1,13 @@
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<%
Exception ex = (Exception) request.getAttribute("exception");
%>
<head><title><%= ex.getMessage() %>
</title></head>
<body>
<h2><%= ex.getMessage() %>
</h2>
<a href='<c:url value="/flights"/>'>Flights</a>
</body>
</html>

View File

@@ -0,0 +1,47 @@
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="joda" uri="http://www.joda.org/joda/time/tags" %>
<html>
<head><title>Flights</title></head>
<body>
<table>
<tr>
<td>Number:</td>
<td>
<c:out value="${flight.number}"/>
</td>
</tr>
<tr>
<td>From:</td>
<td>
<c:out value="${flight.from.city}"/>
(
<c:out value="${flight.from.code}"/>
)
</td>
</tr>
<tr>
<td>Departure:</td>
<td>
<joda:format value="${flight.departureTime}" style="MM"/>
</td>
</tr>
<tr>
<td>To:</td>
<td>
<c:out value="${flight.to.city}"/>
(
<c:out value="${flight.to.code}"/>
)
</td>
</tr>
<tr>
<td>Departure:</td>
<td>
<joda:format value="${flight.arrivalTime}" style="MM"/>
</td>
</tr>
</table>
<a href='<c:url value="/flights.html"/>'>Flights</a>
</body>
</html>

View File

@@ -0,0 +1,73 @@
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="joda" uri="http://www.joda.org/joda/time/tags" %>
<html>
<head><title>Flights</title></head>
<body>
<form a method="get" action='<c:url value="/flights.html"/>'>
<table>
<tr>
<td>From:</td>
<td><input name="from" value='<c:out value="${from}" default="AMS"/>'/></td>
</tr>
<tr>
<td>To:</td>
<td><input name="to" value="<c:out value="${to}" default="VCE"/>"/></td>
</tr>
<tr>
<td>Departure Date:</td>
<td><input name="departureDate" value="<c:out value="${departureDate}" default="2006-01-31"/>"/></td>
</tr>
<tr>
<td>Service Class:</td>
<td>
<select name="serviceClass">
<option value="ECONOMY" selected="selected">Economy</option>
<option value="BUSINESS">Business</option>
<option value="FIRST">First</option>
</select>
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="Submit"/>
</td>
</tr>
</table>
<c:if test="${!empty flights}">
<table border="1px">
<tr>
<th>Number</th>
<th>Departs</th>
<th>Arrives</th>
</tr>
<c:forEach var="flight" items="${flights}">
<tr>
<td>
<spring:url var="flightUrl" value="flights/{id}.html">
<spring:param name="id" value="${flight.id}"/>
</spring:url>
<a href='<c:out value="${flightUrl}"/>'><c:out value="${flight.number}"/></a>
</td>
<td>
<c:out value="${flight.from.city}"/>
(
<c:out value="${flight.from.code}"/>
)
<joda:format value="${flight.departureTime}" style="SS"/>
</td>
<td>
<c:out value="${flight.to.city}"/>
(
<c:out value="${flight.to.code}"/>
)
<joda:format value="${flight.arrivalTime}" style="SS"/>
</td>
</tr>
</c:forEach>
</table>
</c:if>
</form>
</body>
</html>

View File

@@ -0,0 +1,13 @@
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head><title>No Such Flight</title></head>
<body>
<%
Exception ex = (Exception) request.getAttribute("exception");
%>
<h2>No such flight: <%= ex.getMessage() %>
</h2>
<a href='<c:url value="/flights.html"/>'>Flights</a>
</body>
</html>

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<description>
This web application context contains a simple Spring Web MVC web application that shows flights
</description>
<context:component-scan base-package="org.springframework.ws.samples.airline.web"/>
<!-- ===================== HANDLERS ===================================== -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="defaultErrorView" value="error"/>
<property name="exceptionMappings">
<props>
<prop key="org.springframework.ws.samples.airline.service.NoSuchFlightException">noSuchFlight</prop>
</props>
</property>
</bean>
</beans>

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<display-name>Spring-WS Airline Sample</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:org/springframework/ws/samples/airline/dao/jpa/applicationContext-jpa.xml
classpath:org/springframework/ws/samples/airline/service/applicationContext.xml
classpath:org/springframework/ws/samples/airline/security/applicationContext-security.xml
classpath:org/springframework/ws/samples/airline/ws/applicationContext-ws.xml
classpath:org/springframework/ws/samples/airline/jms/applicationContext-jms.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>ws</servlet-name>
<servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ws</servlet-name>
<url-pattern>/services</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>ws</servlet-name>
<url-pattern>*.wsdl</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>mvc</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<mime-mapping>
<extension>xsd</extension>
<mime-type>text/xml</mime-type>
</mime-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<!-- ===================== WSDL DEFINITION ============================== -->
<bean id="airline" class="org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition">
<description>
Builds a WSDL from the airline.xsd.This bean definition represents the airline.wsdl file found
in the root of the web application.
</description>
<property name="schemaCollection" ref="schemaCollection"/>
<property name="portTypeName" value="Airline"/>
<property name="locationUri" value="http://localhost:8080/airline-server/services"/>
<property name="targetNamespace"
value="http://www.springframework.org/spring-ws/samples/airline/definitions"/>
</bean>
</beans>

View File

@@ -0,0 +1,3 @@
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:redirect url="/flights.html"/>

View File

@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.springframework.org/spring-ws/samples/airline/schemas/messages"
xmlns:tns="http://www.springframework.org/spring-ws/samples/airline/schemas/messages"
xmlns:types="http://www.springframework.org/spring-ws/samples/airline/schemas/types"
elementFormDefault="qualified">
<import namespace="http://www.springframework.org/spring-ws/samples/airline/schemas/types"
schemaLocation="types.xsd"/>
<element name="GetFlightsRequest">
<complexType>
<all>
<element name="from" type="types:AirportCode"/>
<element name="to" type="types:AirportCode"/>
<element name="departureDate" type="date"/>
<element name="serviceClass" type="types:ServiceClass" minOccurs="0"/>
</all>
</complexType>
</element>
<element name="GetFlightsResponse">
<complexType>
<sequence>
<element name="flight" type="types:Flight" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
</complexType>
</element>
<element name="BookFlightRequest">
<complexType>
<all>
<element name="flightNumber" type="types:FlightNumber"/>
<element name="departureTime" type="dateTime"/>
<element name="passengers">
<complexType>
<choice maxOccurs="9">
<element name="passenger" type="types:Name"/>
<element name="username" type="types:FrequentFlyerUsername"/>
</choice>
</complexType>
</element>
</all>
</complexType>
</element>
<element name="BookFlightResponse" type="types:Ticket"/>
<element name="GetFrequentFlyerMileageRequest" nillable="true" type="string"/>
<element name="GetFrequentFlyerMileageResponse" type="int"/>
</schema>

View File

@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.springframework.org/spring-ws/samples/airline/schemas/types"
xmlns:tns="http://www.springframework.org/spring-ws/samples/airline/schemas/types"
elementFormDefault="qualified">
<complexType name="Flight">
<sequence>
<element name="number" type="tns:FlightNumber"/>
<element name="departureTime" type="dateTime"/>
<element name="from" type="tns:Airport"/>
<element name="arrivalTime" type="dateTime"/>
<element name="to" type="tns:Airport"/>
<element name="serviceClass" type="tns:ServiceClass"/>
</sequence>
</complexType>
<simpleType name="FlightNumber">
<restriction base="string">
<pattern value="[A-Z][A-Z][0-9][0-9][0-9][0-9]"/>
</restriction>
</simpleType>
<complexType name="Name">
<sequence>
<element name="first" type="string"/>
<element name="last" type="string"/>
</sequence>
</complexType>
<simpleType name="FrequentFlyerUsername">
<restriction base="string"/>
</simpleType>
<complexType name="Airport">
<all>
<element name="code" type="tns:AirportCode"/>
<element name="name" type="string"/>
<element name="city" type="string"/>
</all>
</complexType>
<simpleType name="AirportCode">
<restriction base="string">
<pattern value="[A-Z][A-Z][A-Z]"/>
</restriction>
</simpleType>
<complexType name="Ticket">
<all>
<element name="id" type="long"/>
<element name="issueDate" type="date"/>
<element name="passengers">
<complexType>
<sequence>
<element name="passenger" type="tns:Name" maxOccurs="9"/>
</sequence>
</complexType>
</element>
<element name="flight" type="tns:Flight"/>
</all>
</complexType>
<simpleType name="ServiceClass">
<restriction base="NCName">
<enumeration value="economy"/>
<enumeration value="business"/>
<enumeration value="first"/>
</restriction>
</simpleType>
</schema>

View File

@@ -0,0 +1,124 @@
/*
* Copyright 2005-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.dao.jpa;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.BeforeTransaction;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ws.samples.airline.dao.FlightDao;
import org.springframework.ws.samples.airline.domain.Airport;
import org.springframework.ws.samples.airline.domain.Flight;
import org.springframework.ws.samples.airline.domain.ServiceClass;
import org.joda.time.DateTime;
import org.joda.time.Interval;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("applicationContext-jpa.xml")
@Transactional
public class JpaFlightDaoTest {
private DateTime departureTime;
private DateTime arrivalTime;
private Interval interval;
private Airport fromAirport;
private Airport toAirport;
@Autowired
private FlightDao flightDao;
private JdbcTemplate jdbcTemplate;
@Autowired
public void setDataSource(DataSource dataSource) {
jdbcTemplate = new JdbcTemplate(dataSource);
}
@BeforeTransaction
public void createTestData() {
departureTime = new DateTime(2006, 1, 31, 10, 5, 0, 0);
arrivalTime = new DateTime(2006, 1, 31, 12, 25, 0, 0);
interval = departureTime.toLocalDate().toInterval();
fromAirport = new Airport("RTM", "Rotterdam Airport", "Rotterdam");
toAirport = new Airport("OSL", "Gardermoen", "Oslo");
}
@Before
public void insertTestData() {
jdbcTemplate.update("INSERT INTO AIRPORT(CODE, NAME, CITY) VALUES('RTM', 'Rotterdam Airport', 'Rotterdam')");
jdbcTemplate.update("INSERT INTO AIRPORT(CODE, NAME, CITY) VALUES('OSL', 'Gardermoen', 'Oslo')");
}
@Test
public void getFlightsInPeriod() throws Exception {
jdbcTemplate
.update("INSERT INTO FLIGHT(NUMBER, DEPARTURE_TIME, FROM_AIRPORT_CODE, ARRIVAL_TIME, TO_AIRPORT_CODE, SERVICE_CLASS, SEATS_AVAILABLE, MILES) " +
"VALUES ('KL020','2006-01-31 10:05:00', 'RTM', '2006-01-31 12:25:00', 'OSL', 'BUSINESS', 90, 10)");
List<Flight> flights = flightDao.findFlights("RTM", "OSL", interval, ServiceClass.BUSINESS);
assertNotNull("Invalid result", flights);
assertEquals("Invalid amount of flights", 1, flights.size());
}
@Test
public void getFlightsOutOfPeriod() throws Exception {
jdbcTemplate
.update("INSERT INTO FLIGHT(NUMBER, DEPARTURE_TIME, FROM_AIRPORT_CODE, ARRIVAL_TIME, TO_AIRPORT_CODE, SERVICE_CLASS, SEATS_AVAILABLE, MILES) " +
"VALUES ('KL020','2006-01-31 10:05:00', 'RTM', '2006-01-31 12:25:00', 'OSL', 'BUSINESS', 90, 10)");
DateTime dateTime = new DateTime(2006, 6, 1, 0, 0, 0, 0);
List flights = flightDao.findFlights("RTM", "OSL", new Interval(dateTime, dateTime), ServiceClass.BUSINESS);
assertNotNull("Invalid result", flights);
assertEquals("Invalid amount of flights", 0, flights.size());
}
@Test
public void getFlightByNumberDepartureTime() throws Exception {
jdbcTemplate
.update("INSERT INTO FLIGHT(NUMBER, DEPARTURE_TIME, FROM_AIRPORT_CODE, ARRIVAL_TIME, TO_AIRPORT_CODE, SERVICE_CLASS, SEATS_AVAILABLE, MILES) " +
"VALUES ('KL020','2006-01-31 10:05:00', 'RTM', '2006-01-31 12:25:00', 'OSL', 'BUSINESS', 90, 10)");
Flight flight = flightDao.getFlight("KL020", departureTime);
assertNotNull("No flight returned", flight);
assertNotNull("Invalid flight id", flight.getId());
assertEquals("Invalid flight number", "KL020", flight.getNumber());
assertEquals("Invalid flight departure time", departureTime, flight.getDepartureTime());
assertEquals("Invalid flight arrival time", arrivalTime, flight.getArrivalTime());
assertEquals("Invalid flight from airport", fromAirport, flight.getFrom());
assertEquals("Invalid flight to airport", toAirport, flight.getTo());
assertEquals("Invalid flight service class", ServiceClass.BUSINESS, flight.getServiceClass());
}
@Test
public void noSuchFlight() {
Flight flight = flightDao.getFlight("INVALID", departureTime);
assertNull("Flight returned", flight);
}
}

View File

@@ -0,0 +1,73 @@
/*
* Copyright 2005-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.dao.jpa;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ws.samples.airline.domain.FrequentFlyer;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("applicationContext-jpa.xml")
@Transactional
public class JpaFrequentFlyerDaoTest {
@Autowired
private JpaFrequentFlyerDao frequentFlyerDao;
private JdbcTemplate jdbcTemplate;
@Autowired
public void setDataSource(DataSource dataSource) {
jdbcTemplate = new JdbcTemplate(dataSource);
}
@Before
public void insertTestData() {
jdbcTemplate
.update("INSERT INTO PASSENGER(ID, FIRST_NAME, LAST_NAME) " + "VALUES (42, 'Arjen', 'Poutsma')");
jdbcTemplate
.update("INSERT INTO FREQUENT_FLYER(PASSENGER_ID, USERNAME, PASSWORD, MILES) " +
"VALUES (42, 'arjen', 'changeme', 0)");
}
@Test
public void getByUsername() throws Exception {
FrequentFlyer flyer = frequentFlyerDao.get("arjen");
assertNotNull("No frequent flyer returned", flyer);
assertEquals("Invalid username", "arjen", flyer.getUsername());
assertEquals("Invalid password", "changeme", flyer.getPassword());
assertEquals("Invalid first name", "Arjen", flyer.getFirstName());
assertEquals("Invalid last name", "Poutsma", flyer.getLastName());
}
@Test
public void noSuchUsername() {
FrequentFlyer flyer = frequentFlyerDao.get("invalid");
assertNull("FrequentFlyer returned", flyer);
}
}

View File

@@ -0,0 +1,83 @@
/*
* Copyright 2005-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.dao.jpa;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ws.samples.airline.domain.Flight;
import org.springframework.ws.samples.airline.domain.Passenger;
import org.springframework.ws.samples.airline.domain.Ticket;
import org.joda.time.LocalDate;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("applicationContext-jpa.xml")
@Transactional
public class JpaTicketDaoTest {
@Autowired
private JpaTicketDao ticketDao;
@Autowired
private JpaFlightDao flightDao;
private JdbcTemplate jdbcTemplate;
@Autowired
public void setDataSource(DataSource dataSource) {
jdbcTemplate = new JdbcTemplate(dataSource);
}
@Before
public void insertTestData() {
jdbcTemplate.update("INSERT INTO AIRPORT(CODE, NAME, CITY) VALUES('RTM', 'Rotterdam Airport', 'Rotterdam')");
jdbcTemplate.update("INSERT INTO AIRPORT(CODE, NAME, CITY) VALUES('OSL', 'Gardermoen', 'Oslo')");
jdbcTemplate
.update("INSERT INTO FLIGHT(ID, NUMBER, DEPARTURE_TIME, FROM_AIRPORT_CODE, ARRIVAL_TIME, TO_AIRPORT_CODE, SERVICE_CLASS, SEATS_AVAILABLE, MILES) " +
"VALUES (42, 'KL020','2006-01-31 10:05:00', 'RTM', '2006-01-31 12:25:00', 'OSL', 'BUSINESS', 90, 10)");
}
@Test
public void save() throws Exception {
Passenger passenger = new Passenger("Arjen", "Poutsma");
Flight flight = flightDao.getFlight(42L);
Ticket ticket = new Ticket();
ticket.addPassenger(passenger);
ticket.setFlight(flight);
ticket.setIssueDate(new LocalDate());
int startTicketCount = jdbcTemplate.queryForInt("SELECT COUNT(0) FROM TICKET");
int startPassengerCount = jdbcTemplate.queryForInt("SELECT COUNT(0) FROM PASSENGER");
ticketDao.save(ticket);
assertNotNull("No Id generated", ticket.getId());
int endTicketCount = jdbcTemplate.queryForInt("SELECT COUNT(0) FROM TICKET");
int endPassengerCount = jdbcTemplate.queryForInt("SELECT COUNT(0) FROM PASSENGER");
assertEquals("Flight not inserted", 1, endTicketCount - startTicketCount);
assertEquals("Passenger not inserted", 1, endPassengerCount - startPassengerCount);
}
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright 2005-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.security;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.ws.samples.airline.dao.FrequentFlyerDao;
import org.springframework.ws.samples.airline.domain.FrequentFlyer;
import junit.framework.TestCase;
import static org.easymock.EasyMock.*;
public class SpringFrequentFlyerSecurityServiceTest extends TestCase {
private SpringFrequentFlyerSecurityService securityService;
private FrequentFlyerDao flyerDaoMock;
@Override
protected void setUp() throws Exception {
flyerDaoMock = createMock(FrequentFlyerDao.class);
securityService = new SpringFrequentFlyerSecurityService(flyerDaoMock);
}
public void testGetCurrentlyAuthenticatedFrequentFlyer() throws Exception {
FrequentFlyer frequentFlyer = new FrequentFlyer("john");
FrequentFlyerDetails detail = new FrequentFlyerDetails(frequentFlyer);
TestingAuthenticationToken token = new TestingAuthenticationToken(detail, null);
SecurityContext context = new SecurityContextImpl();
context.setAuthentication(token);
SecurityContextHolder.setContext(context);
replay(flyerDaoMock);
FrequentFlyer result = securityService.getCurrentlyAuthenticatedFrequentFlyer();
assertEquals("Invalid result", frequentFlyer, result);
verify(flyerDaoMock);
}
public void testGetFrequentFlyer() throws Exception {
FrequentFlyer frequentFlyer = new FrequentFlyer("john");
expect(flyerDaoMock.get("john")).andReturn(frequentFlyer);
replay(flyerDaoMock);
FrequentFlyer result = securityService.getFrequentFlyer("john");
assertEquals("Invalid result", frequentFlyer, result);
verify(flyerDaoMock);
}
}

View File

@@ -0,0 +1,184 @@
/*
* Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.service.impl;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import junit.framework.TestCase;
import static org.easymock.EasyMock.*;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.springframework.ws.samples.airline.dao.FlightDao;
import org.springframework.ws.samples.airline.dao.TicketDao;
import org.springframework.ws.samples.airline.domain.Flight;
import org.springframework.ws.samples.airline.domain.FrequentFlyer;
import org.springframework.ws.samples.airline.domain.Passenger;
import org.springframework.ws.samples.airline.domain.ServiceClass;
import org.springframework.ws.samples.airline.domain.Ticket;
import org.springframework.ws.samples.airline.security.FrequentFlyerSecurityService;
import org.springframework.ws.samples.airline.service.NoSeatAvailableException;
import org.springframework.ws.samples.airline.service.NoSuchFlightException;
public class AirlineServiceImplTest extends TestCase {
private AirlineServiceImpl airlineService;
private FlightDao flightDaoMock;
private TicketDao ticketDaoMock;
private FrequentFlyerSecurityService securityServiceMock;
private String flightNumber;
@Override
protected void setUp() throws Exception {
flightDaoMock = createMock(FlightDao.class);
ticketDaoMock = createMock(TicketDao.class);
airlineService = new AirlineServiceImpl(flightDaoMock, ticketDaoMock);
securityServiceMock = createMock(FrequentFlyerSecurityService.class);
airlineService.setFrequentFlyerSecurityService(securityServiceMock);
flightNumber = "AB1234";
}
public void testBookFlight() throws Exception {
DateTime departureTime = new DateTime();
Passenger passenger = new Passenger("John", "Doe");
List<Passenger> passengers = new ArrayList<Passenger>();
passengers.add(passenger);
Flight flight = new Flight();
flight.setNumber(flightNumber);
flight.setSeatsAvailable(10);
expect(flightDaoMock.getFlight(flightNumber, departureTime)).andReturn(flight);
expect(flightDaoMock.update(flight)).andReturn(flight);
Ticket ticket = new Ticket();
ticket.setFlight(flight);
ticketDaoMock.save(isA(Ticket.class));
replay(flightDaoMock, ticketDaoMock, securityServiceMock);
ticket = airlineService.bookFlight(flightNumber, departureTime, passengers);
assertNotNull("Invalid ticket", ticket);
assertEquals("Invalid flight", flight, ticket.getFlight());
assertEquals("Invalid seats available", 9, flight.getSeatsAvailable());
assertEquals("Invalid passengers count", 1, ticket.getPassengers().size());
verify(flightDaoMock, ticketDaoMock, securityServiceMock);
}
public void testBookFlightFrequentFlyer() throws Exception {
DateTime departureTime = new DateTime();
FrequentFlyer frequentFlyer = new FrequentFlyer("John", "Doe", "john", "changeme");
List<Passenger> passengers = new ArrayList<Passenger>();
passengers.add(frequentFlyer);
Flight flight = new Flight();
flight.setNumber(flightNumber);
flight.setSeatsAvailable(1);
flight.setMiles(10);
expect(securityServiceMock.getFrequentFlyer("john")).andReturn(frequentFlyer);
expect(flightDaoMock.getFlight(flightNumber, departureTime)).andReturn(flight);
expect(flightDaoMock.update(flight)).andReturn(flight);
ticketDaoMock.save(isA(Ticket.class));
replay(flightDaoMock, ticketDaoMock, securityServiceMock);
Ticket ticket = airlineService.bookFlight(flightNumber, departureTime, passengers);
assertNotNull("Invalid ticket", ticket);
assertEquals("Invalid flight", flight, ticket.getFlight());
assertEquals("Invalid amount of miles", 10, frequentFlyer.getMiles());
verify(flightDaoMock, ticketDaoMock, securityServiceMock);
}
public void testBookFlightNoSeatAvailable() throws Exception {
DateTime departureTime = new DateTime();
List<Passenger> passengers = Collections.singletonList(new Passenger());
Flight flight = new Flight();
flight.setNumber("AB1234");
flight.setDepartureTime(new DateTime());
expect(flightDaoMock.getFlight(flightNumber, departureTime)).andReturn(flight);
replay(flightDaoMock, ticketDaoMock, securityServiceMock);
try {
airlineService.bookFlight(flightNumber, departureTime, passengers);
fail("Should have thrown an NoSeatAvailableException");
}
catch (NoSeatAvailableException ex) {
}
verify(flightDaoMock, ticketDaoMock, securityServiceMock);
}
public void testBookFlightNoSuchFlight() throws Exception {
String flightNumber = "AB1234";
DateTime departureTime = new DateTime();
List<Passenger> passengers = Collections.singletonList(new Passenger());
expect(flightDaoMock.getFlight(flightNumber, departureTime)).andReturn(null);
replay(flightDaoMock, ticketDaoMock, securityServiceMock);
try {
airlineService.bookFlight(flightNumber, departureTime, passengers);
fail("Should have thrown an NoSuchFlightException");
}
catch (NoSuchFlightException ex) {
}
verify(flightDaoMock, ticketDaoMock, securityServiceMock);
}
public void testGetFlights() throws Exception {
LocalDate departureDate = new LocalDate(2006, 1, 31);
Flight flight = new Flight();
List<Flight> flights = new ArrayList<Flight>();
flights.add(flight);
String toCode = "to";
String fromCode = "from";
expect(flightDaoMock.findFlights(fromCode, toCode, departureDate.toInterval(), ServiceClass.ECONOMY))
.andReturn(flights);
replay(flightDaoMock, ticketDaoMock, securityServiceMock);
List<Flight> result = airlineService.getFlights(fromCode, toCode, departureDate, ServiceClass.ECONOMY);
assertEquals("Invalid result", flights, result);
verify(flightDaoMock, ticketDaoMock, securityServiceMock);
}
public void testGetFlightsDefaultServiceClass() throws Exception {
LocalDate departureDate = new LocalDate(2006, 1, 31);
Flight flight = new Flight();
List<Flight> flights = new ArrayList<Flight>();
flights.add(flight);
String toCode = "to";
String fromCode = "from";
expect(flightDaoMock.findFlights(fromCode, toCode, departureDate.toInterval(), ServiceClass.ECONOMY))
.andReturn(flights);
replay(flightDaoMock, ticketDaoMock, securityServiceMock);
List<Flight> result = airlineService.getFlights(fromCode, toCode, departureDate, null);
assertEquals("Invalid result", flights, result);
verify(flightDaoMock, ticketDaoMock, securityServiceMock);
}
}

View File

@@ -0,0 +1,62 @@
/*
* Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.web;
import java.util.ArrayList;
import java.util.List;
import junit.framework.TestCase;
import static org.easymock.EasyMock.*;
import org.joda.time.LocalDate;
import org.springframework.ui.ModelMap;
import org.springframework.ws.samples.airline.domain.Flight;
import org.springframework.ws.samples.airline.domain.ServiceClass;
import org.springframework.ws.samples.airline.service.AirlineService;
public class FlightsControllerTest extends TestCase {
private FlightsController flightsController;
private AirlineService airlineServiceMock;
@Override
protected void setUp() throws Exception {
airlineServiceMock = createMock(AirlineService.class);
flightsController = new FlightsController(airlineServiceMock);
}
public void testFlightList() throws Exception {
String from = "AMS";
String to = "VCE";
LocalDate departureDate = new LocalDate();
ServiceClass serviceClass = ServiceClass.FIRST;
List<Flight> flights = new ArrayList<Flight>();
flights.add(new Flight());
expect(airlineServiceMock.getFlights(from, to, departureDate, serviceClass)).andReturn(flights);
replay(airlineServiceMock);
ModelMap model = new ModelMap();
String view = flightsController
.flightList(from, to, departureDate.toString(), serviceClass.toString(), model);
assertNotNull("No view returned", view);
assertEquals("Invalid view name", "flights", view);
assertTrue("No flights in ModelAndView", model.containsAttribute("flights"));
verify(airlineServiceMock);
}
}

View File

@@ -0,0 +1,207 @@
/*
* Copyright 2005-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.ws;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.xml.bind.JAXBElement;
import javax.xml.datatype.DatatypeConstants;
import javax.xml.datatype.DatatypeFactory;
import org.springframework.ws.samples.airline.domain.Airport;
import org.springframework.ws.samples.airline.domain.FrequentFlyer;
import org.springframework.ws.samples.airline.domain.Passenger;
import org.springframework.ws.samples.airline.schema.BookFlightRequest;
import org.springframework.ws.samples.airline.schema.Flight;
import org.springframework.ws.samples.airline.schema.GetFlightsResponse;
import org.springframework.ws.samples.airline.schema.Name;
import org.springframework.ws.samples.airline.schema.ObjectFactory;
import org.springframework.ws.samples.airline.schema.ServiceClass;
import org.springframework.ws.samples.airline.schema.Ticket;
import org.springframework.ws.samples.airline.service.AirlineService;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.LocalDate;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.w3c.dom.Element;
import static org.easymock.EasyMock.*;
import static org.junit.Assert.assertNotNull;
public class AirlineEndpointTest {
private AirlineEndpoint endpoint;
private AirlineService airlineServiceMock;
private DatatypeFactory datatypeFactory;
private ObjectFactory objectFactory;
@Before
public void setUp() throws Exception {
airlineServiceMock = createMock(AirlineService.class);
endpoint = new AirlineEndpoint(airlineServiceMock);
datatypeFactory = DatatypeFactory.newInstance();
objectFactory = new ObjectFactory();
}
@Test
public void testGetFlights() throws Exception {
org.springframework.ws.samples.airline.domain.Flight domainFlight = createDomainFlight();
expect(airlineServiceMock.getFlights("ABC", "DEF", new LocalDate(2007, 6, 13),
org.springframework.ws.samples.airline.domain.ServiceClass.FIRST))
.andReturn(Collections.singletonList(domainFlight));
replay(airlineServiceMock);
GetFlightsResponse response = endpoint.getFlights("ABC", "DEF", "2007-06-13", "first");
Assert.assertEquals("Invalid amount of flights received", 1, response.getFlight().size());
Flight schemaFlight = response.getFlight().get(0);
verifySchemaFlight(schemaFlight);
verify(airlineServiceMock);
}
private void verifySchemaFlight(Flight schemaFlight) {
Assert.assertEquals("Invalid number", "ABC1234", schemaFlight.getNumber());
Assert.assertEquals("Invalid departure time",
datatypeFactory.newXMLGregorianCalendar(2007, 6, 13, 12, 0, 0, 0, 0), schemaFlight.getDepartureTime());
Assert.assertEquals("Invalid from code", "ABC", schemaFlight.getFrom().getCode());
Assert.assertEquals("Invalid from name", "ABC Airport", schemaFlight.getFrom().getName());
Assert.assertEquals("Invalid from city", "ABC City", schemaFlight.getFrom().getCity());
Assert.assertEquals("Invalid arrival time",
datatypeFactory.newXMLGregorianCalendar(2007, 6, 13, 14, 0, 0, 0, 0), schemaFlight.getArrivalTime());
Assert.assertEquals("Invalid to code", "DEF", schemaFlight.getTo().getCode());
Assert.assertEquals("Invalid to name", "DEF Airport", schemaFlight.getTo().getName());
Assert.assertEquals("Invalid to city", "DEF City", schemaFlight.getTo().getCity());
Assert.assertEquals("Invalid service class", ServiceClass.FIRST, schemaFlight.getServiceClass());
}
private org.springframework.ws.samples.airline.domain.Flight createDomainFlight() {
org.springframework.ws.samples.airline.domain.Flight domainFlight =
new org.springframework.ws.samples.airline.domain.Flight();
domainFlight.setNumber("ABC1234");
domainFlight.setDepartureTime(new DateTime(2007, 6, 13, 12, 0, 0, 0, DateTimeZone.UTC));
domainFlight.setFrom(new Airport("ABC", "ABC Airport", "ABC City"));
domainFlight.setArrivalTime(new DateTime(2007, 6, 13, 14, 0, 0, 0, DateTimeZone.UTC));
domainFlight.setTo(new Airport("DEF", "DEF Airport", "DEF City"));
domainFlight.setServiceClass(org.springframework.ws.samples.airline.domain.ServiceClass.FIRST);
return domainFlight;
}
@Test
public void bookFlightPassenger() throws Exception {
BookFlightRequest request = objectFactory.createBookFlightRequest();
request.setDepartureTime(datatypeFactory.newXMLGregorianCalendar(2007, 6, 13, 12, 0, 0, 0, 0));
request.setFlightNumber("ABC1234");
Name passengerName = new Name();
passengerName.setFirst("John");
passengerName.setLast("Doe");
BookFlightRequest.Passengers passengers = new BookFlightRequest.Passengers();
passengers.getPassengerOrUsername().add(passengerName);
request.setPassengers(passengers);
Passenger domainPassenger = new Passenger("John", "Doe");
org.springframework.ws.samples.airline.domain.Ticket domainTicket =
new org.springframework.ws.samples.airline.domain.Ticket(42L);
domainTicket.setFlight(createDomainFlight());
domainTicket.setIssueDate(new LocalDate(2007, 6, 13));
domainTicket.setPassengers(Collections.singleton(domainPassenger));
expect(airlineServiceMock.bookFlight("ABC1234", new DateTime(2007, 6, 13, 12, 0, 0, 0, DateTimeZone.UTC),
Collections.singletonList(domainPassenger))).andReturn(domainTicket);
replay(airlineServiceMock);
JAXBElement<Ticket> response = endpoint.bookFlight(request);
Ticket schemaTicket = response.getValue();
Assert.assertEquals("Invalid id", 42L, schemaTicket.getId());
Assert.assertEquals("Invalid issue date",
datatypeFactory.newXMLGregorianCalendarDate(2007, 6, 13, DatatypeConstants.FIELD_UNDEFINED),
schemaTicket.getIssueDate());
Assert.assertEquals("Invalid amount of passengers", 1, schemaTicket.getPassengers().getPassenger().size());
Name schemaPassenger = schemaTicket.getPassengers().getPassenger().get(0);
Assert.assertEquals("Invalid passenger first name", "John", schemaPassenger.getFirst());
Assert.assertEquals("Invalid passenger first name", "Doe", schemaPassenger.getLast());
verifySchemaFlight(schemaTicket.getFlight());
verify(airlineServiceMock);
}
@Test
public void testBookFlightFrequentFlyer() throws Exception {
BookFlightRequest request = objectFactory.createBookFlightRequest();
request.setDepartureTime(datatypeFactory.newXMLGregorianCalendar(2007, 6, 13, 12, 0, 0, 0, 0));
request.setFlightNumber("ABC1234");
BookFlightRequest.Passengers passengers = new BookFlightRequest.Passengers();
passengers.getPassengerOrUsername().add("john");
request.setPassengers(passengers);
FrequentFlyer domainFrequentFlyer = new FrequentFlyer("John", "Doe", "john", "changeme");
Set<Passenger> domainPassengers = new HashSet<Passenger>();
domainPassengers.add(domainFrequentFlyer);
org.springframework.ws.samples.airline.domain.Ticket domainTicket =
new org.springframework.ws.samples.airline.domain.Ticket(42L);
domainTicket.setFlight(createDomainFlight());
domainTicket.setIssueDate(new LocalDate(2007, 6, 13));
domainTicket.setPassengers(domainPassengers);
List<Passenger> domainPassengerList = new ArrayList<Passenger>(domainPassengers);
expect(airlineServiceMock
.bookFlight("ABC1234", new DateTime(2007, 6, 13, 12, 0, 0, 0, DateTimeZone.UTC), domainPassengerList))
.andReturn(domainTicket);
replay(airlineServiceMock);
JAXBElement<Ticket> response = endpoint.bookFlight(request);
Ticket schemaTicket = response.getValue();
Assert.assertEquals("Invalid id", 42L, schemaTicket.getId());
Assert.assertEquals("Invalid issue date",
datatypeFactory.newXMLGregorianCalendarDate(2007, 6, 13, DatatypeConstants.FIELD_UNDEFINED),
schemaTicket.getIssueDate());
Assert.assertEquals("Invalid amount of passengers", 1, schemaTicket.getPassengers().getPassenger().size());
Name schemaPassenger = schemaTicket.getPassengers().getPassenger().get(0);
Assert.assertEquals("Invalid passenger first name", "John", schemaPassenger.getFirst());
Assert.assertEquals("Invalid passenger first name", "Doe", schemaPassenger.getLast());
verifySchemaFlight(schemaTicket.getFlight());
verify(airlineServiceMock);
}
@Test
public void testGetFrequentFlyerMileage() throws Exception {
expect(airlineServiceMock.getFrequentFlyerMileage()).andReturn(42);
replay(airlineServiceMock);
Element response = endpoint.getFrequentFlyerMileage();
assertNotNull("Invalid response", response);
verify(airlineServiceMock);
}
}

2
airline/settings.gradle Normal file
View File

@@ -0,0 +1,2 @@
include "server", "client:axis1", "client:jax-ws", "client:jms", "client:saaj", "client:spring-ws"