Moved Spring-WS to separate dir.

This commit is contained in:
Arjen Poutsma
2006-09-24 19:22:56 +00:00
commit 66d3aef26c
623 changed files with 44122 additions and 0 deletions

View File

@@ -0,0 +1 @@
DROP DATABASE IF EXISTS airline;

View File

@@ -0,0 +1,53 @@
CREATE DATABASE IF NOT EXISTS airline;
GRANT ALL ON airline.* TO airline@localhost IDENTIFIED BY 'airline';
USE airline;
CREATE TABLE AIRPORT (
CODE CHAR(3) NOT NULL PRIMARY KEY,
NAME VARCHAR(20) NOT NULL,
CITY VARCHAR(20) NOT NULL
);
CREATE TABLE FLIGHT (
ID INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
NUMBER VARCHAR(20) NOT NULL,
DEPARTURE_TIME DATETIME NOT NULL,
FROM_AIRPORT_CODE CHAR(3) NOT NULL REFERENCES AIRPORT(CODE),
ARRIVAL_TIME DATETIME NOT NULL,
TO_AIRPORT_CODE CHAR(3) NOT NULL REFERENCES AIRPORT(CODE),
SERVICE_CLASS VARCHAR(10) NOT NULL,
SEATS_AVAILABLE INT(4) UNSIGNED NOT NULL,
MILES INT(4) UNSIGNED NOT NULL,
UNIQUE KEY IDX_NUMBER_DEPARTURE_TIME (NUMBER, DEPARTURE_TIME)
);
CREATE TABLE TICKET (
ID INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
ISSUE_DATE DATE NOT NULL,
FLIGHT_ID INT(4) UNSIGNED NOT NULL REFERENCES FLIGHT(ID)
);
CREATE TABLE PASSENGER (
ID INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
FIRST_NAME VARCHAR(30),
LAST_NAME VARCHAR(30)
);
CREATE TABLE PASSENGER_TICKET (
PASSENGER_ID INT(4) UNSIGNED NOT NULL REFERENCES PASSENGER(ID),
TICKET_ID INT(4) UNSIGNED NOT NULL REFERENCES TICKET(ID)
);
CREATE TABLE FREQUENT_FLYER (
PASSENGER_ID INT(4) UNSIGNED NOT NULL PRIMARY KEY REFERENCES PASSENGER(ID),
USERNAME VARCHAR(10) NOT NULL,
PASSWORD VARCHAR(10) NOT NULL,
MILES INT(4) UNSIGNED NOT NULL,
UNIQUE KEY IDX_USERNAME (USERNAME)
);

View File

@@ -0,0 +1,8 @@
INSERT INTO AIRPORT(CODE, NAME, CITY) VALUES('AMS', 'Schiphol Airport', 'Amsterdam');
INSERT INTO AIRPORT(CODE, NAME, CITY) VALUES('VCE', 'Marco Polo Airport', 'Venice');
INSERT INTO FLIGHT(ID, NUMBER, DEPARTURE_TIME, FROM_AIRPORT_CODE, ARRIVAL_TIME, TO_AIRPORT_CODE, SERVICE_CLASS, SEATS_AVAILABLE, MILES) VALUES (1,'KL1653','2006-01-31 10:05:00', 'AMS', '2006-01-31 12:25:00', 'VCE', 'economy', 5, 200);
INSERT INTO FLIGHT(ID, NUMBER, DEPARTURE_TIME, FROM_AIRPORT_CODE, ARRIVAL_TIME, TO_AIRPORT_CODE, SERVICE_CLASS, SEATS_AVAILABLE, MILES) VALUES (2,'KL1654','2006-02-05 12:40:00', 'VCE', '2006-02-05 14:15:00', 'AMS', 'economy', 5, 200);
INSERT INTO PASSENGER(ID, FIRST_NAME, LAST_NAME) VALUES (1, 'John', 'Doe');
INSERT INTO FREQUENT_FLYER(PASSENGER_ID, USERNAME, PASSWORD, MILES) VALUES (1, 'john', 'changeme', 10);

View File

@@ -0,0 +1,6 @@
DROP TABLE FREQUENT_FLYER;
DROP TABLE PASSENGER_TICKET;
DROP TABLE PASSENGER;
DROP TABLE TICKET;
DROP TABLE FLIGHT;
DROP TABLE AIRPORT;

View File

@@ -0,0 +1,46 @@
CREATE DATABASE airline;
GRANT ALL ON DATABASE airline to airline;
CREATE TABLE AIRPORT (
CODE CHAR(3) NOT NULL PRIMARY KEY,
NAME VARCHAR(20) NOT NULL,
CITY VARCHAR(20) NOT NULL
);
CREATE TABLE FLIGHT (
ID BIGSERIAL NOT NULL PRIMARY KEY,
NUMBER VARCHAR(20) NOT NULL,
DEPARTURE_TIME TIMESTAMP NOT NULL,
FROM_AIRPORT_CODE CHAR(3) NOT NULL REFERENCES AIRPORT(CODE),
ARRIVAL_TIME TIMESTAMP NOT NULL,
TO_AIRPORT_CODE CHAR(3) NOT NULL REFERENCES AIRPORT(CODE),
SERVICE_CLASS VARCHAR(10) NOT NULL,
SEATS_AVAILABLE INT NOT NULL,
MILES INT NOT NULL,
UNIQUE(NUMBER, DEPARTURE_TIME)
);
CREATE TABLE TICKET (
ID BIGSERIAL NOT NULL PRIMARY KEY,
ISSUE_DATE DATE NOT NULL,
FLIGHT_ID INT NOT NULL REFERENCES FLIGHT(ID)
);
CREATE TABLE PASSENGER (
ID BIGSERIAL NOT NULL PRIMARY KEY,
FIRST_NAME VARCHAR(30),
LAST_NAME VARCHAR(30)
);
CREATE TABLE PASSENGER_TICKET (
PASSENGER_ID INT NOT NULL REFERENCES PASSENGER(ID),
TICKET_ID INT NOT NULL REFERENCES TICKET(ID)
);
CREATE TABLE FREQUENT_FLYER (
PASSENGER_ID INT NOT NULL PRIMARY KEY REFERENCES PASSENGER(ID),
USERNAME VARCHAR(10) NOT NULL,
PASSWORD VARCHAR(10) NOT NULL,
MILES INT NOT NULL,
UNIQUE (USERNAME)
);

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<BookFlightRequest xmlns="http://www.springframework.org/spring-ws/samples/airline/schemas">
<flightNumber>EF1234</flightNumber>
<departureTime>2006-01-01T00:00:00.000Z</departureTime>
<passengers>
<passenger>
<first>John</first>
<last>Doe</last>
</passenger>
</passengers>
</BookFlightRequest>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<BookFlightRequest xmlns="http://www.springframework.org/spring-ws/samples/airline/schemas">
<flightNumber>EF1234</flightNumber>
<departureTime>2006-01-01T00:00:00.000Z</departureTime>
<passengers>
<username>john</username>
</passengers>
</BookFlightRequest>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<BookFlightResponse xmlns="http://www.springframework.org/spring-ws/samples/airline/schemas">
<id>42</id>
<issueDate>2006-01-01</issueDate>
<passengers>
<passenger>
<first>John</first>
<last>Doe</last>
</passenger>
</passengers>
<flight>
<number>EF1234</number>
<departureTime>2006-01-01T00:00:00Z</departureTime>
<from>
<code>ABC</code>
<name>Airport</name>
<city>City</city>
</from>
<arrivalTime>2006-02-02T00:00:00Z</arrivalTime>
<to>
<code>DEF</code>
<name>Airport</name>
<city>City</city>
</to>
<serviceClass>economy</serviceClass>
</flight>
</BookFlightResponse>

View File

@@ -0,0 +1,37 @@
/*
* 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.springframework.dao.DataAccessException;
import org.springframework.ws.samples.airline.domain.Flight;
import org.springframework.ws.samples.airline.domain.ServiceClass;
public interface FlightDao {
List findFlights(String fromAirportCode,
String toAirportCode,
DateTime startOfPeriod,
DateTime endOfPeriod,
ServiceClass serviceClass) throws DataAccessException;
Flight getFlight(String flightNumber, DateTime departureTime);
void update(Flight flight);
}

View File

@@ -0,0 +1,28 @@
/*
* 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;
void update(FrequentFlyer frequentFlyer) 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,52 @@
/*
* 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.hibernate;
import java.util.List;
import org.joda.time.DateTime;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.ws.samples.airline.dao.FlightDao;
import org.springframework.ws.samples.airline.domain.Flight;
import org.springframework.ws.samples.airline.domain.ServiceClass;
public class HibernateFlightDao extends HibernateDaoSupport implements FlightDao {
public Flight getFlight(String flightNumber, DateTime departureTime) {
List flights = getHibernateTemplate().findByNamedParam(
"from Flight f where f.number = :number and " + "f.departureTime = :departureTime",
new String[]{"number", "departureTime"}, new Object[]{flightNumber, departureTime});
return !flights.isEmpty() ? (Flight) flights.get(0) : null;
}
public void update(Flight flight) {
getHibernateTemplate().update(flight);
}
public List findFlights(String fromAirportCode,
String toAirportCode,
DateTime startOfPeriod,
DateTime endOfPeriod,
ServiceClass serviceClass) throws DataAccessException {
return getHibernateTemplate().findByNamedParam("from Flight f where f.from.code = :from " +
"and f.to.code = :to and " + "f.departureTime >= :start and f.departureTime <= :end and " +
"f.serviceClass = :class", new String[]{"from", "to", "start", "end", "class"},
new Object[]{fromAirportCode, toAirportCode, startOfPeriod, endOfPeriod, serviceClass});
}
}

View File

@@ -0,0 +1,37 @@
/*
* 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.hibernate;
import java.util.List;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.util.CollectionUtils;
import org.springframework.ws.samples.airline.dao.FrequentFlyerDao;
import org.springframework.ws.samples.airline.domain.FrequentFlyer;
public class HibernateFrequentFlyerDao extends HibernateDaoSupport implements FrequentFlyerDao {
public FrequentFlyer get(String username) {
List flyers = getHibernateTemplate().find("from FrequentFlyer f where f.username = ?", username);
return !CollectionUtils.isEmpty(flyers) ? (FrequentFlyer) flyers.get(0) : null;
}
public void update(FrequentFlyer frequentFlyer) throws DataAccessException {
getHibernateTemplate().update(frequentFlyer);
}
}

View File

@@ -0,0 +1,29 @@
/*
* 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.hibernate;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.ws.samples.airline.dao.TicketDao;
import org.springframework.ws.samples.airline.domain.Ticket;
public class HibernateTicketDao extends HibernateDaoSupport implements TicketDao {
public void save(Ticket ticket) throws DataAccessException {
getHibernateTemplate().save(ticket);
}
}

View File

@@ -0,0 +1,76 @@
/*
* 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;
public class Airport implements Serializable {
private String code;
private String name;
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 void setCity(String city) {
this.city = city;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof Airport)) {
return false;
}
final Airport that = (Airport) other;
return this.code.equals(that.code);
}
public int hashCode() {
return code.hashCode();
}
}

View File

@@ -0,0 +1,32 @@
/*
* 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.domain;
import java.io.Serializable;
public class Entity implements Serializable {
private Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}

View File

@@ -0,0 +1,140 @@
/*
* 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 org.joda.time.DateTime;
public class Flight extends Entity {
private String number;
private DateTime departureTime;
private DateTime arrivalTime;
private Airport to;
private Airport from;
private ServiceClass serviceClass;
private int seatsAvailable;
private int miles;
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 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;
}
if (!number.equals(flight.number)) {
return false;
}
return true;
}
public int hashCode() {
int result;
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());
return buffer.toString();
}
public void substractSeats(int count) {
this.seatsAvailable -= count;
}
}

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.domain;
public class FrequentFlyer extends Passenger {
private String username;
private String password;
private int miles;
public FrequentFlyer() {
}
public FrequentFlyer(String username) {
this.username = username;
}
public FrequentFlyer(String username, String password, String firstName, String lastName) {
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 this.username.equals(that.username);
}
public int hashCode() {
return username.hashCode();
}
public void addMiles(int miles) {
this.miles += miles;
}
}

View File

@@ -0,0 +1,78 @@
/*
* 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 org.springframework.util.Assert;
public class Passenger extends Entity {
private String firstName;
private String lastName;
public Passenger() {
}
public Passenger(String firstName, String lastName) {
Assert.hasLength(firstName);
Assert.hasLength(lastName);
this.firstName = firstName;
this.lastName = 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;
result = getFirstName().hashCode();
result = 29 * result + getLastName().hashCode();
return result;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}

View File

@@ -0,0 +1,56 @@
/*
* 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.HashMap;
import java.util.Map;
public class ServiceClass implements Serializable {
private String name;
public static final ServiceClass ECONOMY = new ServiceClass("economy");
public static final ServiceClass BUSINESS = new ServiceClass("business");
public static final ServiceClass FIRST = new ServiceClass("first");
private static final Map INSTANCES = new HashMap();
static {
INSTANCES.put(ECONOMY.toString(), ECONOMY);
INSTANCES.put(BUSINESS.toString(), BUSINESS);
INSTANCES.put(FIRST.toString(), FIRST);
}
private ServiceClass(String name) {
this.name = name;
}
public String toString() {
return name;
}
Object readResolve() {
return getInstance(name);
}
public static ServiceClass getInstance(String name) {
return (ServiceClass) INSTANCES.get(name);
}
}

View File

@@ -0,0 +1,59 @@
/*
* 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.util.HashSet;
import java.util.Set;
import org.joda.time.YearMonthDay;
public class Ticket extends Entity {
private YearMonthDay issueDate;
private Set passengers = new HashSet();
private Flight flight;
public Flight getFlight() {
return flight;
}
public void setFlight(Flight flight) {
this.flight = flight;
}
public YearMonthDay getIssueDate() {
return issueDate;
}
public void setIssueDate(YearMonthDay issueDate) {
this.issueDate = issueDate;
}
public Set getPassengers() {
return passengers;
}
public void setPassengers(Set passengers) {
this.passengers = passengers;
}
public void addPassenger(Passenger passenger) {
passengers.add(passenger);
}
}

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.domain.hibernate;
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;
import org.springframework.ws.samples.airline.domain.ServiceClass;
public class ServiceClassUserType implements UserType {
private static final int[] SQL_TYPES = {Types.VARCHAR};
public boolean isMutable() {
return false;
}
public int[] sqlTypes() {
return SQL_TYPES;
}
public Class returnedClass() {
return ServiceClass.class;
}
public boolean equals(Object x, Object y) {
return x == y;
}
public int hashCode(Object object) throws HibernateException {
return object.hashCode();
}
public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner)
throws HibernateException, SQLException {
String name = resultSet.getString(names[0]);
return resultSet.wasNull() ? null : ServiceClass.getInstance(name);
}
public void nullSafeSet(PreparedStatement statement, Object value, int index)
throws HibernateException, SQLException {
if (value == null) {
statement.setNull(index, Types.VARCHAR);
}
else {
statement.setString(index, value.toString());
}
}
public Object deepCopy(Object value) {
return value;
}
public Serializable disassemble(Object object) throws HibernateException {
return (Serializable) object;
}
public Object assemble(Serializable serializable, Object object) throws HibernateException {
return serializable;
}
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return original;
}
}

View File

@@ -0,0 +1,59 @@
/*
* 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.acegisecurity.Authentication;
import org.acegisecurity.context.SecurityContext;
import org.acegisecurity.context.SecurityContextHolder;
import org.springframework.ws.samples.airline.dao.FrequentFlyerDao;
import org.springframework.ws.samples.airline.domain.FrequentFlyer;
/**
* Implementation of the <code>FrequentFlyerSecurityService</code> that uses Acegi.
*
* @author Arjen Poutsma
*/
public class AcegiFrequentFlyerSecurityService implements FrequentFlyerSecurityService {
private FrequentFlyerDao frequentFlyerDao;
public void setFrequentFlyerDao(FrequentFlyerDao frequentFlyerDao) {
this.frequentFlyerDao = frequentFlyerDao;
}
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;
}
}
public FrequentFlyer getFrequentFlyer(String username) {
return frequentFlyerDao.get(username);
}
}

View File

@@ -0,0 +1,73 @@
/*
* 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.acegisecurity.GrantedAuthority;
import org.acegisecurity.GrantedAuthorityImpl;
import org.acegisecurity.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 GrantedAuthority[] GRANTED_AUTHORITIES =
new GrantedAuthority[]{new GrantedAuthorityImpl("ROLE_FREQUENT_FLYER")};
public FrequentFlyerDetails(FrequentFlyer frequentFlyer) {
this.frequentFlyer = frequentFlyer;
}
public 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;
}
}

View File

@@ -0,0 +1,49 @@
/*
* 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.acegisecurity.userdetails.UserDetails;
import org.acegisecurity.userdetails.UserDetailsService;
import org.acegisecurity.userdetails.UsernameNotFoundException;
import org.springframework.dao.DataAccessException;
import org.springframework.ws.samples.airline.dao.FrequentFlyerDao;
import org.springframework.ws.samples.airline.domain.FrequentFlyer;
/**
* Implementation of the Acegi <code>UserDetailsService</code> for <code>FrequentFlyerDetails</code>.
*
* @author Arjen Poutsma
*/
public class FrequentFlyerDetailsService implements UserDetailsService {
private FrequentFlyerDao frequentFlyerDao;
public void setFrequentFlyerDao(FrequentFlyerDao frequentFlyerDao) {
this.frequentFlyerDao = frequentFlyerDao;
}
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,43 @@
/*
* 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;
/**
* 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
*/
FrequentFlyer getFrequentFlyer(String username);
/**
* 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,53 @@
/*
* 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.jdom.Element;
import org.jdom.Namespace;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.ws.endpoint.AbstractJDomPayloadEndpoint;
import org.springframework.ws.samples.airline.service.AirlineService;
/**
* Endpoint that returns the amount of frequent flyer miles for the currently logged in user. Secured via a WS-Security
* UsernameToken
*
* @author Arjen Poutsma
*/
public class GetFrequentFlyerMileageEndpoint extends AbstractJDomPayloadEndpoint implements InitializingBean {
private AirlineService airlineService;
private Namespace namespace;
public void setAirlineService(AirlineService airlineService) {
this.airlineService = airlineService;
}
protected Element invokeInternal(Element ignored) throws Exception {
int result = airlineService.getFrequentFlyerMileage();
Element response = new Element("GetFrequentFlyerMileageResponse", namespace);
response.setText(Integer.toString(result));
return response;
}
public void afterPropertiesSet() throws Exception {
namespace = Namespace.getNamespace("tns", "http://www.springframework.org/spring-ws/samples/airline/schemas");
}
}

View File

@@ -0,0 +1,71 @@
/*
* 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.YearMonthDay;
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 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
* @see org.springframework.ws.samples.airline.domain.Flight
*/
List getFlights(String fromAirportCode,
String toAirportCode,
YearMonthDay 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 <code>FrequentFlyer</code> 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 <code>Passenger</code>s with a
* first and last name, or <code>FrequentFlyer</code>s 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
* @see org.springframework.ws.samples.airline.domain.Passenger
* @see org.springframework.ws.samples.airline.domain.FrequentFlyer
*/
Ticket bookFlight(String flightNumber, DateTime departureTime, List passengers)
throws NoSuchFlightException, NoSeatAvailableException;
/**
* 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,38 @@
/*
* 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;
/**
* Exception thrown when not enough seats are available for a flight.
*
* @author Arjen Poutsma
*/
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,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.service;
import org.joda.time.DateTime;
/**
* Exception thrown when a specified flight cannot be found.
*
* @author Arjen Poutsma
*/
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 String getFlightNumber() {
return flightNumber;
}
public DateTime getDepartureTime() {
return departureTime;
}
}

View File

@@ -0,0 +1,123 @@
/*
* 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.impl;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.joda.time.DateTime;
import org.joda.time.YearMonthDay;
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.service.AirlineService;
import org.springframework.ws.samples.airline.service.NoSeatAvailableException;
import org.springframework.ws.samples.airline.service.NoSuchFlightException;
/**
* Default implementation of the <code>AirlineService</code> interface.
*
* @author Arjen Poutsma
*/
public class AirlineServiceImpl implements AirlineService {
private final static Log logger = LogFactory.getLog(AirlineServiceImpl.class);
private FlightDao flightDao;
private TicketDao ticketDao;
private FrequentFlyerSecurityService frequentFlyerSecurityService;
public void setFlightDao(FlightDao flightDao) {
this.flightDao = flightDao;
}
public void setFrequentFlyerSecurityService(FrequentFlyerSecurityService frequentFlyerSecurityService) {
this.frequentFlyerSecurityService = frequentFlyerSecurityService;
}
public void setTicketDao(TicketDao ticketDao) {
this.ticketDao = ticketDao;
}
public Ticket bookFlight(String flightNumber, DateTime departureTime, List passengers)
throws NoSuchFlightException, NoSeatAvailableException {
Assert.notEmpty(passengers, "No passengers given");
if (logger.isDebugEnabled()) {
logger.debug("Booking flight '" + flightNumber + "' on '" + departureTime + "' for " + passengers.size() +
" 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 YearMonthDay());
ticket.setFlight(flight);
for (Iterator iterator = passengers.iterator(); iterator.hasNext();) {
Passenger passenger = (Passenger) iterator.next();
// 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 int getFrequentFlyerMileage() {
FrequentFlyer frequentFlyer = frequentFlyerSecurityService.getCurrentlyAuthenticatedFrequentFlyer();
return frequentFlyer.getMiles();
}
public List getFlights(String fromAirportCode,
String toAirportCode,
YearMonthDay departureDate,
ServiceClass serviceClass) {
if (serviceClass == null) {
serviceClass = ServiceClass.ECONOMY;
}
if (logger.isDebugEnabled()) {
logger.debug(
"Getting flights from '" + fromAirportCode + "' to '" + toAirportCode + "' on " + departureDate);
}
DateTime startOfPeriod = departureDate.toDateTimeAtMidnight();
DateTime endOfPeriod = startOfPeriod.plusDays(1);
return flightDao.findFlights(fromAirportCode, toAirportCode, startOfPeriod, endOfPeriod, serviceClass);
}
}

View File

@@ -0,0 +1,166 @@
/*
* 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.ws;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.jdom.Element;
import org.jdom.Namespace;
import org.jdom.xpath.XPath;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.YearMonthDay;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.ws.endpoint.AbstractJDomPayloadEndpoint;
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.Passenger;
import org.springframework.ws.samples.airline.domain.ServiceClass;
import org.springframework.ws.samples.airline.domain.Ticket;
import org.springframework.ws.samples.airline.service.AirlineService;
public class BookFlightEndpoint extends AbstractJDomPayloadEndpoint implements InitializingBean {
private AirlineService airlineService;
private XPath flightNumberXPath;
private XPath departureTimeXPath;
private Namespace namespace;
private DateTimeFormatter dateFormatter;
private DateTimeFormatter dateTimeFormatter;
private DateTimeFormatter parser;
private XPath passengersXPath;
public void setAirlineService(AirlineService airlineService) {
this.airlineService = airlineService;
}
protected Element invokeInternal(Element requestElement) throws Exception {
String flightNumber = flightNumberXPath.valueOf(requestElement);
String departureTimeString = departureTimeXPath.valueOf(requestElement);
DateTime departureTime = parser.parseDateTime(departureTimeString);
if (logger.isDebugEnabled()) {
logger.debug("BookFlight request for flight number [" + flightNumber + "] at [" + departureTime + "]");
}
List passengerElements = passengersXPath.selectNodes(requestElement);
List passengers = new ArrayList();
for (Iterator iterator = passengerElements.iterator(); iterator.hasNext();) {
Element passengerElement = (Element) iterator.next();
if ("passenger".equals(passengerElement.getName()) && namespace.equals(passengerElement.getNamespace())) {
Passenger passenger = new Passenger(passengerElement.getChildTextNormalize("first", namespace),
passengerElement.getChildTextNormalize("last", namespace));
passengers.add(passenger);
}
else
if ("username".equals(passengerElement.getName()) && namespace.equals(passengerElement.getNamespace())) {
FrequentFlyer frequentFlyer = new FrequentFlyer(passengerElement.getTextNormalize());
passengers.add(frequentFlyer);
}
}
Ticket ticket = airlineService.bookFlight(flightNumber, departureTime, passengers);
return createResponse(ticket);
}
private Element createResponse(Ticket ticket) {
Element responseElement = new Element("BookFlightResponse", namespace);
responseElement.addContent(new Element("id", namespace).setText(ticket.getId().toString()));
responseElement.addContent(createIssueDateElement(ticket.getIssueDate()));
responseElement.addContent(createPassengersElement(ticket.getPassengers()));
responseElement.addContent(createFlightElement(ticket.getFlight()));
return responseElement;
}
protected Element createIssueDateElement(YearMonthDay issueDate) {
Element issueDateElement = new Element("issueDate", namespace);
issueDateElement.setText(dateFormatter.print(issueDate));
return issueDateElement;
}
protected Element createPassengersElement(Set passengers) {
Element passengersElement = new Element("passengers", namespace);
for (Iterator iterator = passengers.iterator(); iterator.hasNext();) {
Passenger passenger = (Passenger) iterator.next();
Element passengerElement = new Element("passenger", namespace);
passengersElement.addContent(passengerElement);
passengerElement.addContent(new Element("first", namespace).setText(passenger.getFirstName()));
passengerElement.addContent(new Element("last", namespace).setText(passenger.getLastName()));
}
return passengersElement;
}
protected Element createFlightElement(Flight flight) {
Element flightElement = new Element("flight", namespace);
flightElement.addContent(new Element("number", namespace).setText(flight.getNumber()));
flightElement.addContent(new Element("departureTime",
namespace).setText(dateTimeFormatter.print(flight.getDepartureTime())));
flightElement.addContent(createAirportElement("from", flight.getFrom()));
flightElement
.addContent(new Element("arrivalTime",
namespace).setText(dateTimeFormatter.print(flight.getArrivalTime())));
flightElement.addContent(createAirportElement("to", flight.getTo()));
flightElement.addContent(createServiceClassElement(flight.getServiceClass()));
return flightElement;
}
protected Element createAirportElement(String localName, Airport airport) {
Element airportElement = new Element(localName, namespace);
airportElement.addContent(new Element("code", namespace).setText(airport.getCode()));
airportElement.addContent(new Element("name", namespace).setText(airport.getName()));
airportElement.addContent(new Element("city", namespace).setText(airport.getCity()));
return airportElement;
}
protected Element createServiceClassElement(ServiceClass serviceClass) {
Element serviceClassElement = new Element("serviceClass", namespace);
if (ServiceClass.BUSINESS.equals(serviceClass)) {
serviceClassElement.setText("business");
}
else if (ServiceClass.ECONOMY.equals(serviceClass)) {
serviceClassElement.setText("economy");
}
else if (ServiceClass.FIRST.equals(serviceClass)) {
serviceClassElement.setText("first");
}
return serviceClassElement;
}
public void afterPropertiesSet() throws Exception {
namespace = Namespace.getNamespace("tns", "http://www.springframework.org/spring-ws/samples/airline/schemas");
flightNumberXPath = XPath.newInstance("/tns:BookFlightRequest/tns:flightNumber/text()");
flightNumberXPath.addNamespace(namespace);
departureTimeXPath = XPath.newInstance("/tns:BookFlightRequest/tns:departureTime/text()");
departureTimeXPath.addNamespace(namespace);
passengersXPath = XPath.newInstance("/tns:BookFlightRequest/tns:passengers/*");
passengersXPath.addNamespace(namespace);
parser = ISODateTimeFormat.dateTimeParser().withZone(DateTimeZone.UTC);
dateTimeFormatter = ISODateTimeFormat.dateTimeNoMillis();
dateFormatter = ISODateTimeFormat.date();
}
}

View File

@@ -0,0 +1,131 @@
/*
* 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.ws;
import java.util.Iterator;
import java.util.List;
import org.joda.time.YearMonthDay;
import org.joda.time.chrono.ISOChronology;
import org.springframework.ws.endpoint.AbstractMarshallingPayloadEndpoint;
import org.springframework.ws.samples.airline.schema.Airport;
import org.springframework.ws.samples.airline.schema.Flight;
import org.springframework.ws.samples.airline.schema.GetFlightsRequest;
import org.springframework.ws.samples.airline.schema.GetFlightsResponse;
import org.springframework.ws.samples.airline.schema.ServiceClass;
import org.springframework.ws.samples.airline.schema.impl.AirportImpl;
import org.springframework.ws.samples.airline.schema.impl.FlightImpl;
import org.springframework.ws.samples.airline.schema.impl.GetFlightsResponseImpl;
import org.springframework.ws.samples.airline.service.AirlineService;
/**
* Endpoint that returns a list of flights with a given number, and that lie between a given start and end date. It uses
* JAXB-based marshalling for both request and response objects. Because we use separate POJOs for our schema and our
* domain objects, we need to convert the response domain objects to schema-based objects.
*
* @author Arjen Poutsma
*/
public class GetFlightsEndpoint extends AbstractMarshallingPayloadEndpoint {
private AirlineService airlineService;
public void setAirlineService(AirlineService airlineService) {
this.airlineService = airlineService;
}
protected Object invokeInternal(Object requestObject) throws Exception {
GetFlightsRequest request = (GetFlightsRequest) requestObject;
YearMonthDay departureDate = new YearMonthDay(request.getDepartureDate(), ISOChronology.getInstance());
if (logger.isDebugEnabled()) {
logger.debug("Request for flights from '" + request.getFrom() + "' to '" + request.getTo() + "' on " +
departureDate);
}
List flights = airlineService.getFlights(request.getFrom(), request.getTo(), departureDate,
convertToDomainType(request.getServiceClass()));
if (logger.isDebugEnabled()) {
logger.debug("Marshalling " + flights.size() + " flight results");
}
GetFlightsResponse response = new GetFlightsResponseImpl();
for (Iterator iter = flights.iterator(); iter.hasNext();) {
org.springframework.ws.samples.airline.domain.Flight domainFlight =
(org.springframework.ws.samples.airline.domain.Flight) iter.next();
Flight schemaFlight = convertToSchemaType(domainFlight);
response.getFlight().add(schemaFlight);
}
return response;
}
private Flight convertToSchemaType(org.springframework.ws.samples.airline.domain.Flight domainFlight) {
Flight schemaFlight = new FlightImpl();
schemaFlight.setNumber(domainFlight.getNumber());
schemaFlight.setDepartureTime(domainFlight.getDepartureTime().toGregorianCalendar());
schemaFlight.setFrom(convertToSchemaType(domainFlight.getFrom()));
schemaFlight.setArrivalTime(domainFlight.getArrivalTime().toGregorianCalendar());
schemaFlight.setTo(convertToSchemaType(domainFlight.getTo()));
schemaFlight.setServiceClass(convertToSchemaType(domainFlight.getServiceClass()));
return schemaFlight;
}
private Airport convertToSchemaType(org.springframework.ws.samples.airline.domain.Airport domainAirport) {
if (domainAirport == null) {
return null;
}
Airport schemaAirport = new AirportImpl();
schemaAirport.setCode(domainAirport.getCode());
schemaAirport.setName(domainAirport.getName());
schemaAirport.setCity(domainAirport.getCity());
return schemaAirport;
}
private ServiceClass convertToSchemaType(org.springframework.ws.samples.airline.domain.ServiceClass domainServiceClass) {
if (domainServiceClass == null) {
return null;
}
else if (domainServiceClass.equals(org.springframework.ws.samples.airline.domain.ServiceClass.BUSINESS)) {
return ServiceClass.BUSINESS;
}
else if (domainServiceClass.equals(org.springframework.ws.samples.airline.domain.ServiceClass.ECONOMY)) {
return ServiceClass.ECONOMY;
}
else if (domainServiceClass.equals(org.springframework.ws.samples.airline.domain.ServiceClass.FIRST)) {
return ServiceClass.FIRST;
}
else {
throw new IllegalArgumentException("Invalid domain service class: [" + domainServiceClass + "]");
}
}
private org.springframework.ws.samples.airline.domain.ServiceClass convertToDomainType(ServiceClass schemaServiceClass) {
if (schemaServiceClass == null) {
return null;
}
else if (schemaServiceClass.equals(ServiceClass.BUSINESS)) {
return org.springframework.ws.samples.airline.domain.ServiceClass.BUSINESS;
}
else if (schemaServiceClass.equals(ServiceClass.ECONOMY)) {
return org.springframework.ws.samples.airline.domain.ServiceClass.ECONOMY;
}
else if (schemaServiceClass.equals(ServiceClass.FIRST)) {
return org.springframework.ws.samples.airline.domain.ServiceClass.FIRST;
}
else {
throw new IllegalArgumentException("Invalid schema service class: [" + schemaServiceClass + "]");
}
}
}

View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="abstractDao" abstract="true">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="flightDao" class="org.springframework.ws.samples.airline.dao.hibernate.HibernateFlightDao"
parent="abstractDao"/>
<bean id="ticketDao" class="org.springframework.ws.samples.airline.dao.hibernate.HibernateTicketDao"
parent="abstractDao"/>
<bean id="frequentFlyerDao" class="org.springframework.ws.samples.airline.dao.hibernate.HibernateFrequentFlyerDao"
parent="abstractDao"/>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mappingLocations">
<list>
<value>classpath:org/springframework/ws/samples/airline/domain/hibernate/airline.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<bean class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location"
value="classpath:org/springframework/ws/samples/airline/dao/hibernate/hibernate.properties"/>
</bean>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations" value="classpath:org/springframework/ws/samples/airline/dao/jdbc.properties"/>
</bean>
</beans>

View File

@@ -0,0 +1,8 @@
# Properties file with hibernate-related settings.
#hibernate.dialect=org.hibernate.dialect.HSQLDialect
hibernate.dialect=org.hibernate.dialect.MySQLInnoDBDialect
#hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
hibernate.cache.provider_class=org.hibernate.cache.HashtableCacheProvider
#hibernate.hbm2ddl.auto=create-drop
#hibernate.show_sql=true

View File

@@ -0,0 +1,14 @@
#jdbc.driverClassName=org.hsqldb.jdbcDriver
#jdbc.username=sa
#jdbc.password=
#jdbc.url=jdbc:hsqldb:mem:airline
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.username=airline
jdbc.password=airline
jdbc.url=jdbc:mysql://localhost/airline
#jdbc.driverClassName=org.postgresql.Driver
#jdbc.username=airline
#jdbc.password=airline
#jdbc.url=jdbc:postgresql://localhost/airline

View File

@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping
package="org.springframework.ws.samples.airline.domain"
auto-import="true" default-lazy="false">
<class name="Passenger" table="PASSENGER">
<id name="id" column="ID">
<generator class="identity"/>
</id>
<property name="firstName" column="FIRST_NAME"/>
<property name="lastName" column="LAST_NAME"/>
<joined-subclass name="FrequentFlyer" table="FREQUENT_FLYER">
<key column="PASSENGER_ID"/>
<property name="miles" column="MILES"/>
<property name="password" column="PASSWORD"/>
<property name="username" column="USERNAME"/>
</joined-subclass>
</class>
<class name="Flight" table="FLIGHT">
<id name="id" column="ID">
<generator class="identity"/>
</id>
<property name="number" column="NUMBER" length="20" unique="true" unique-key="number-departureTime"/>
<property name="departureTime" column="DEPARTURE_TIME" unique="true" unique-key="number-departureTime"
type="org.joda.time.contrib.hibernate.PersistentDateTime"/>
<property name="arrivalTime" column="ARRIVAL_TIME" type="org.joda.time.contrib.hibernate.PersistentDateTime"/>
<property name="seatsAvailable" column="SEATS_AVAILABLE"/>
<property name="miles" column="MILES"/>
<many-to-one name="from" column="FROM_AIRPORT_CODE" class="Airport"/>
<many-to-one name="to" column="TO_AIRPORT_CODE" class="Airport"/>
<property name="serviceClass" column="SERVICE_CLASS"
type="org.springframework.ws.samples.airline.domain.hibernate.ServiceClassUserType"/>
</class>
<class name="Airport" table="AIRPORT">
<id name="code" column="CODE">
<generator class="assigned"/>
</id>
<property name="name" column="NAME"/>
<property name="city" column="CITY"/>
</class>
<class name="Ticket" table="TICKET">
<id name="id" column="ID">
<generator class="identity"/>
</id>
<property name="issueDate" column="ISSUE_DATE" type="org.joda.time.contrib.hibernate.PersistentYearMonthDay"/>
<set name="passengers" table="PASSENGER_TICKET" cascade="save-update">
<key column="TICKET_ID"/>
<many-to-many class="Passenger" column="PASSENGER_ID"/>
</set>
<many-to-one name="flight" column="FLIGHT_ID" class="Flight" cascade="none"/>
</class>
</hibernate-mapping>

View File

@@ -0,0 +1,111 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<description>
This application context contains the WS-Security and Acegi beans.
</description>
<bean id="securityService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<description>
A transactional security service used to obtain Frequent Flyer information.
</description>
<property name="target">
<bean class="org.springframework.ws.samples.airline.security.AcegiFrequentFlyerSecurityService">
<property name="frequentFlyerDao" ref="frequentFlyerDao"/>
</bean>
</property>
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributes">
<props>
<prop key="get*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<!-- ===================== WS-SECURITY ============================== -->
<bean id="secureMapping" class="org.springframework.ws.soap.endpoint.mapping.SoapActionEndpointMapping">
<description>
This SOAP Action endpoint mapping is used for endpoints that are secured via WS-Security. It uses a
securityInterceptor to validate incoming messages.
</description>
<property name="mappings">
<props>
<prop key="http://www.springframework.org/spring-ws/samples/airline/GetFrequentFlyerMileage">
getFrequentFlyerMileageEndpoint</prop>
</props>
</property>
<property name="interceptors">
<list>
<bean class="org.springframework.ws.soap.endpoint.interceptor.SoapEnvelopeLoggingInterceptor"/>
<ref local="wsSecurityInterceptor"/>
</list>
</property>
</bean>
<bean id="wsSecurityInterceptor" class="org.springframework.ws.soap.security.xwss.XwsSecurityInterceptor">
<description>
This interceptor validates incoming messages according to the policy defined in 'securityPolicy.xml'.
The policy defines that all incoming requests must have a UsernameToken with a password digest in it.
The actual authentication is performed by the Acegi callback handler.
</description>
<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.acegi.AcegiDigestPasswordValidationCallbackHandler">
<property name="userDetailsService" ref="userDetailsService"/>
</bean>
</property>
</bean>
<bean id="getFrequentFlyerMileageEndpoint"
class="org.springframework.ws.samples.airline.security.GetFrequentFlyerMileageEndpoint">
<description>
This endpoint handles get frequent flier mileage requests.
</description>
<property name="airlineService" ref="airlineService"/>
</bean>
<!-- ======================== ACEGI AUTHENTICATION ======================= -->
<bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
<description>
A standard Acegi authentication manager.
</description>
<property name="providers">
<bean class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userDetailsService"/>
</bean>
</property>
</bean>
<bean id="userDetailsService" class="org.springframework.ws.samples.airline.security.FrequentFlyerDetailsService">
<property name="frequentFlyerDao" ref="frequentFlyerDao"/>
</bean>
<bean id="loggerListener" class="org.acegisecurity.event.authentication.LoggerListener"/>
<!-- ======================== ACEGI AUTHORIZATION =========================== -->
<bean id="methodSecurityInterceptor"
class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
<property name="authenticationManager">
<ref local="authenticationManager"/>
</property>
<property name="accessDecisionManager">
<bean class="org.acegisecurity.vote.UnanimousBased">
<property name="decisionVoters">
<bean class="org.acegisecurity.vote.RoleVoter"/>
</property>
</bean>
</property>
<property name="objectDefinitionSource">
<value>
org.springframework.ws.samples.airline.service.AirlineService.getFrequentFlyerMileage=ROLE_FREQUENT_FLYER
</value>
</property>
</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,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="airlineServiceTarget" class="org.springframework.ws.samples.airline.service.impl.AirlineServiceImpl">
<property name="flightDao" ref="flightDao"/>
<property name="ticketDao" ref="ticketDao"/>
<!-- Remove the following line if you want to disable WS-Security and Acegi -->
<property name="frequentFlyerSecurityService" ref="securityService"/>
</bean>
<bean id="airlineService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="target" ref="airlineServiceTarget"/>
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributes">
<props>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="book*">PROPAGATION_REQUIRED</prop>
</props>
</property>
<!-- Remove the following line if you want to disable WS-Security and Acegi -->
<property name="postInterceptors" ref="methodSecurityInterceptor"/>
</bean>
</beans>

View File

@@ -0,0 +1,121 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<description>
This application context contains the Spring-WS beans.</description>
<bean id="messageDispatcher" class="org.springframework.ws.soap.SoapMessageDispatcher">
<description>
The MessageDispatcher is responsible for routing messages to endpoints.</description>
<property name="endpointMappings">
<list>
<ref local="payloadMapping"/>
<ref local="soapActionMapping"/>
<!-- Remove the following line if you want to disable WS-Security and Acegi -->
<ref bean="secureMapping"/>
</list>
</property>
<property name="endpointExceptionResolvers">
<list>
<ref local="endpointExceptionResolver"/>
</list>
</property>
</bean>
<bean id="payloadMapping" class="org.springframework.ws.endpoint.mapping.PayloadRootQNameEndpointMapping">
<description>
This endpoint mapping uses the qualified name of the payload (body contents) to determine the endpoint for
an incoming message. The name GetFlightsRequest with namespace
http://www.springframework.org/spring-ws/samples/airline/schemas is mapped to the getFlightsEndpoint.
Additionally, messages are logged using the logging interceptor.</description>
<property name="mappings">
<props>
<prop key="{http://www.springframework.org/spring-ws/samples/airline/schemas}GetFlightsRequest">
getFlightsEndpoint</prop>
</props>
</property>
<property name="interceptors">
<ref local="loggingInterceptor"/>
</property>
</bean>
<bean id="soapActionMapping" class="org.springframework.ws.soap.endpoint.mapping.SoapActionEndpointMapping">
<description>
This endpoint mapping uses SOAP Actions to determine the endpoint for an incoming message. The key
http://www.springframework.org/spring-ws/samples/airline/BookFlight is mapped to the bookFlightEndpoint.
Additionally, message are logged and validated.</description>
<property name="mappings">
<props>
<prop key="http://www.springframework.org/spring-ws/samples/airline/BookFlight">
bookFlightEndpoint</prop>
</props>
</property>
<property name="interceptors">
<list>
<ref local="loggingInterceptor"/>
<ref local="validatingInterceptor"/>
</list>
</property>
</bean>
<bean id="validatingInterceptor" class="org.springframework.ws.endpoint.interceptor.PayloadValidatingInterceptor">
<description>
This interceptor validates both incoming and outgoing message contents according to the 'airline.xsd' XML
Schema file.</description>
<property name="schema" value="airline.xsd"/>
<property name="validateRequest" value="true"/>
<property name="validateResponse" value="true"/>
</bean>
<bean id="loggingInterceptor" class="org.springframework.ws.endpoint.interceptor.PayloadLoggingInterceptor">
<description>
This interceptor logs the message payload.</description>
</bean>
<bean id="bookFlightEndpoint" class="org.springframework.ws.samples.airline.ws.BookFlightEndpoint">
<description>
This endpoint handles book flight request.</description>
<property name="airlineService" ref="airlineService"/>
</bean>
<bean id="getFlightsEndpoint" class="org.springframework.ws.samples.airline.ws.GetFlightsEndpoint">
<description>
This endpoint handles get flights request.</description>
<property name="airlineService" ref="airlineService"/>
<property name="marshaller" ref="jaxbMarshaller"/>
<property name="unmarshaller" ref="jaxbMarshaller"/>
</bean>
<bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb1Marshaller">
<description>
The validating JAXB Marshaller is used by the getFlightsEndpoint to unmarshal XML to objects and
vice-versa.</description>
<property name="contextPath" value="org.springframework.ws.samples.airline.schema"/>
<property name="validating" value="true"/>
</bean>
<bean id="endpointExceptionResolver" class="org.springframework.ws.soap.endpoint.SoapFaultMappingExceptionResolver">
<description>
This exception resolver maps exceptions to SOAP Faults. The business logic exceptions
NoSeatAvailableException and NoSuchFlightException are mapped to custom SOAP Fault. Both
UnmarshallingException andValidationFailureException are mapped to a SOAP Fault with a "Sender" fault code.
All other exceptions are mapped to a "Receiver" error code, the default.</description>
<property name="defaultFault">
<value>RECEIVER,Server error</value>
</property>
<property name="exceptionMappings">
<props>
<prop key="org.springframework.ws.samples.airline.service.NoSeatAvailableException">
{http://www.springframework.org/spring-ws/samples/airline}airline:NoMoreSeats, No more seats
available</prop>
<prop key="org.springframework.ws.samples.airline.service.NoSuchFlightException">
{http://www.springframework.org/spring-ws/samples/airline}airline:NoSuchFlight, No such flight
exists</prop>
<prop key="org.springframework.oxm.UnmarshallingFailureException">SENDER,Invalid request</prop>
<prop key="org.springframework.oxm.ValidationFailureException">SENDER,Invalid request</prop>
</props>
</property>
</bean>
</beans>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="handlerAdapter"
class="org.springframework.ws.transport.http.MessageEndpointHandlerAdapter">
<description>
The handlerAdapter makes sure that Spring's DispatcherServlet
supports MessageEndpoints instances as handlers.
It uses a SAAJ to construct SoapMessageContexts (and SoapMessages).
</description>
<property name="messageContextFactory" ref="messageContextFactory"/>
</bean>
<bean id="messageContextFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageContextFactory"/>
<bean id="handlerMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<description>
All incoming request are mapped to the messageDispatcher defined in applicationContext-ws.xml
</description>
<property name="defaultHandler" ref="messageDispatcher"/>
</bean>
</beans>

View File

@@ -0,0 +1,15 @@
log4j.rootLogger=WARN, stdout, logfile
log4j.logger.org.springframework.oxm=DEBUG
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
log4j.appender.logfile=org.apache.log4j.RollingFileAppender
log4j.appender.logfile.File=${airline.root}/WEB-INF/airline.log
log4j.appender.logfile.MaxFileSize=512KB
log4j.appender.logfile.MaxBackupIndex=3
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n

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>webAppRootKey</param-name>
<param-value>airline.root</param-value>
</context-param>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/log4j.properties</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:org/springframework/ws/samples/airline/dao/hibernate/applicationContext-hibernate.xml
classpath:org/springframework/ws/samples/airline/service/applicationContext.xml
<!-- Remove the following line if you want to disable WS-Security and Acegi -->
classpath:org/springframework/ws/samples/airline/security/applicationContext-security.xml
classpath:org/springframework/ws/samples/airline/ws/applicationContext-ws.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>airline</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>airline</servlet-name>
<url-pattern>/Airline</url-pattern>
</servlet-mapping>
<mime-mapping>
<extension>wsdl</extension>
<mime-type>text/xml</mime-type>
</mime-mapping>
<mime-mapping>
<extension>xsd</extension>
<mime-type>text/xml</mime-type>
</mime-mapping>
</web-app>

View File

@@ -0,0 +1,82 @@
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="airline"
targetNamespace="http://www.springframework.org/spring-ws/samples/airline/definitions"
xmlns:tns="http://www.springframework.org/spring-ws/samples/airline/definitions"
xmlns:types="http://www.springframework.org/spring-ws/samples/airline/schemas"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
<types>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:import namespace="http://www.springframework.org/spring-ws/samples/airline/schemas"
schemaLocation="airline.xsd"/>
</xsd:schema>
</types>
<message name="GetFlightsInput">
<part element="types:GetFlightsRequest" name="body"/>
</message>
<message name="GetFlightsOutput">
<part element="types:GetFlightsResponse" name="body"/>
</message>
<message name="BookFlightInput">
<part element="types:BookFlightRequest" name="body"/>
</message>
<message name="BookFlightOutput">
<part element="types:BookFlightResponse" name="body"/>
</message>
<message name="GetFrequentFlyerMileageInput">
<part element="types:GetFrequentFlyerMileageRequest" name="body"/>
</message>
<message name="GetFrequentFlyerMileageOutput">
<part element="types:GetFrequentFlyerMileageResponse" name="body"/>
</message>
<portType name="AirlinePortType">
<operation name="GetFlights">
<input message="tns:GetFlightsInput"/>
<output message="tns:GetFlightsOutput"/>
</operation>
<operation name="BookFlight">
<input message="tns:BookFlightInput"/>
<output message="tns:BookFlightOutput"/>
</operation>
<operation name="GetFrequentFlyerMileage">
<input message="tns:GetFrequentFlyerMileageInput"/>
<output message="tns:GetFrequentFlyerMileageOutput"/>
</operation>
</portType>
<binding name="AirlineSoapBinding" type="tns:AirlinePortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="GetFlights">
<soap:operation soapAction="http://www.springframework.org/spring-ws/samples/airline/GetFlights"/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
<operation name="BookFlight">
<soap:operation soapAction="http://www.springframework.org/spring-ws/samples/airline/BookFlight"/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
<operation name="GetFrequentFlyerMileage">
<soap:operation
soapAction="http://www.springframework.org/spring-ws/samples/airline/GetFrequentFlyerMileage"/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="AirlineService">
<port binding="tns:AirlineSoapBinding" name="AirlinePort">
<soap:address location="http://localhost:8080/airline/Airline"/>
</port>
</service>
</definitions>

View File

@@ -0,0 +1,118 @@
<?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"
xmlns:tns="http://www.springframework.org/spring-ws/samples/airline/schemas"
elementFormDefault="qualified">
<element name="GetFlightsRequest">
<complexType>
<all>
<element name="from" type="tns:AirportCode"/>
<element name="to" type="tns:AirportCode"/>
<element name="departureDate" type="date"/>
<element name="serviceClass" type="tns:ServiceClass" minOccurs="0"/>
</all>
</complexType>
</element>
<element name="GetFlightsResponse">
<complexType>
<sequence>
<element name="flight" type="tns:Flight" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
</complexType>
</element>
<element name="BookFlightRequest">
<complexType>
<all>
<element name="flightNumber" type="tns:FlightNumber"/>
<element name="departureTime" type="dateTime"/>
<element name="passengers">
<complexType>
<choice maxOccurs="9">
<element name="passenger" type="tns:Name"/>
<element name="username" type="tns:FrequentFlyerUsername"/>
</choice>
</complexType>
</element>
</all>
</complexType>
</element>
<element name="BookFlightResponse" type="tns:Ticket"/>
<element name="GetFrequentFlyerMileageRequest"/>
<element name="GetFrequentFlyerMileageResponse" type="int"/>
<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,105 @@
/*
* 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.hibernate;
import java.util.List;
import org.joda.time.DateTime;
import org.springframework.test.AbstractTransactionalDataSourceSpringContextTests;
import org.springframework.ws.samples.airline.domain.Airport;
import org.springframework.ws.samples.airline.domain.Flight;
import org.springframework.ws.samples.airline.domain.ServiceClass;
public class HibernateFlightDaoTest extends AbstractTransactionalDataSourceSpringContextTests {
private HibernateFlightDao flightDao;
private Airport fromAirport;
private Airport toAirport;
private DateTime departureTime;
private DateTime arrivalTime;
protected String[] getConfigLocations() {
return new String[]{
"classpath:org/springframework/ws/samples/airline/dao/hibernate/applicationContext-hibernate.xml"};
}
public void setFlightDao(HibernateFlightDao flightDao) {
this.flightDao = flightDao;
}
protected void onSetUpBeforeTransaction() throws Exception {
departureTime = new DateTime(2006, 1, 31, 10, 5, 0, 0);
arrivalTime = new DateTime(2006, 1, 31, 12, 25, 0, 0);
}
protected void onSetUpInTransaction() throws Exception {
jdbcTemplate.update("INSERT INTO AIRPORT(CODE, NAME, CITY) VALUES('RTM', 'Rotterdam Airport', 'Rotterdam')");
fromAirport = new Airport("RTM", "Rotterdam Airport", "Rotterdam");
jdbcTemplate.update("INSERT INTO AIRPORT(CODE, NAME, CITY) VALUES('OSL', 'Gardermoen', 'Oslo')");
toAirport = new Airport("OSL", "Gardermoen", "Oslo");
}
public void testGetFlightsInPeriod() 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 flights = flightDao.findFlights("RTM", "OSL", departureTime, arrivalTime, ServiceClass.BUSINESS);
assertNotNull("Invalid result", flights);
assertEquals("Invalid amount of flights", 1, flights.size());
}
public void testGetFlightsOutOfPeriod() 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", dateTime, dateTime, ServiceClass.BUSINESS);
assertNotNull("Invalid result", flights);
assertEquals("Invalid amount of flights", 0, flights.size());
}
public void testGetFlightByNumberDepartureTime() 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());
}
public void testUpdate() 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);
flight.setSeatsAvailable(0);
flightDao.update(flight);
flightDao.getHibernateTemplate().flush();
int count = jdbcTemplate
.queryForInt("SELECT SEATS_AVAILABLE FROM FLIGHT WHERE ID = ?", new Object[]{flight.getId()});
assertEquals("Flight not updated", 0, count);
}
}

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.dao.hibernate;
import org.springframework.test.AbstractTransactionalDataSourceSpringContextTests;
import org.springframework.ws.samples.airline.domain.FrequentFlyer;
public class HibernateFrequentFlyerDaoTest extends AbstractTransactionalDataSourceSpringContextTests {
private HibernateFrequentFlyerDao dao;
protected String[] getConfigLocations() {
return new String[]{
"classpath:org/springframework/ws/samples/airline/dao/hibernate/applicationContext-hibernate.xml"};
}
public void setDao(HibernateFrequentFlyerDao dao) {
this.dao = dao;
}
public void testGetByUsername() throws Exception {
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)");
FrequentFlyer flyer = dao.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());
}
}

View File

@@ -0,0 +1,91 @@
/*
* 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.hibernate;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.YearMonthDay;
import org.springframework.test.AbstractTransactionalDataSourceSpringContextTests;
import org.springframework.ws.samples.airline.domain.Airport;
import org.springframework.ws.samples.airline.domain.Flight;
import org.springframework.ws.samples.airline.domain.Passenger;
import org.springframework.ws.samples.airline.domain.ServiceClass;
import org.springframework.ws.samples.airline.domain.Ticket;
public class HibernateTicketDaoTest extends AbstractTransactionalDataSourceSpringContextTests {
private HibernateTicketDao dao;
private Flight flight;
private DateTime departureTime;
private DateTime arrivalTime;
private Passenger passenger;
protected String[] getConfigLocations() {
return new String[]{
"classpath:org/springframework/ws/samples/airline/dao/hibernate/applicationContext-hibernate.xml"};
}
public void setDao(HibernateTicketDao dao) {
this.dao = dao;
}
protected void onSetUpBeforeTransaction() throws Exception {
departureTime = new DateTime(2006, 1, 31, 10, 5, 0, 0, DateTimeZone.UTC);
arrivalTime = new DateTime(2006, 1, 31, 12, 25, 0, 0, DateTimeZone.UTC);
}
protected void onSetUpInTransaction() throws Exception {
jdbcTemplate.update("INSERT INTO AIRPORT(CODE, NAME, CITY) VALUES('RTM', 'Rotterdam Airport', 'Rotterdam')");
Airport fromAirport = new Airport("RTM", "Rotterdam Airport", "Rotterdam");
jdbcTemplate.update("INSERT INTO AIRPORT(CODE, NAME, CITY) VALUES('OSL', 'Gardermoen', 'Oslo')");
Airport toAirport = new Airport("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)");
flight = new Flight();
flight.setId(new Long(42));
flight.setNumber("KL1653");
flight.setDepartureTime(departureTime);
flight.setFrom(fromAirport);
flight.setArrivalTime(arrivalTime);
flight.setTo(toAirport);
flight.setServiceClass(ServiceClass.BUSINESS);
flight.setSeatsAvailable(90);
passenger = new Passenger();
passenger.setFirstName("John");
passenger.setLastName("Doe");
}
public void testInsert() throws Exception {
Ticket ticket = new Ticket();
ticket.addPassenger(passenger);
ticket.setFlight(flight);
ticket.setIssueDate(new YearMonthDay());
int startTicketCount = jdbcTemplate.queryForInt("SELECT COUNT(0) FROM TICKET");
int startPassengerCount = jdbcTemplate.queryForInt("SELECT COUNT(0) FROM PASSENGER");
dao.save(ticket);
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,65 @@
/*
* 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 junit.framework.TestCase;
import org.acegisecurity.context.SecurityContext;
import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.context.SecurityContextImpl;
import org.acegisecurity.providers.TestingAuthenticationToken;
import org.easymock.MockControl;
import org.springframework.ws.samples.airline.dao.FrequentFlyerDao;
import org.springframework.ws.samples.airline.domain.FrequentFlyer;
public class AcegiFrequentFlyerSecurityServiceTest extends TestCase {
private AcegiFrequentFlyerSecurityService securityService;
private MockControl control;
private FrequentFlyerDao mock;
protected void setUp() throws Exception {
securityService = new AcegiFrequentFlyerSecurityService();
control = MockControl.createControl(FrequentFlyerDao.class);
mock = (FrequentFlyerDao) control.getMock();
securityService.setFrequentFlyerDao(mock);
}
public void testGetCurrentlyAuthenticatedFrequentFlyer() throws Exception {
FrequentFlyer frequentFlyer = new FrequentFlyer("john");
FrequentFlyerDetails detail = new FrequentFlyerDetails(frequentFlyer);
TestingAuthenticationToken token = new TestingAuthenticationToken(detail, null, null);
SecurityContext context = new SecurityContextImpl();
context.setAuthentication(token);
SecurityContextHolder.setContext(context);
control.replay();
FrequentFlyer result = securityService.getCurrentlyAuthenticatedFrequentFlyer();
assertEquals("Invalid result", frequentFlyer, result);
control.verify();
}
public void testGetFrequentFlyer() throws Exception {
FrequentFlyer frequentFlyer = new FrequentFlyer("john");
control.expectAndReturn(mock.get("john"), frequentFlyer);
control.replay();
FrequentFlyer result = securityService.getFrequentFlyer("john");
assertEquals("Invalid result", frequentFlyer, result);
control.verify();
}
}

View File

@@ -0,0 +1,53 @@
/*
* 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 junit.framework.TestCase;
import org.easymock.MockControl;
import org.jdom.Element;
import org.springframework.ws.samples.airline.service.AirlineService;
public class GetFrequentFlyerMileageEndpointTest extends TestCase {
private GetFrequentFlyerMileageEndpoint endpoint;
private MockControl control;
private AirlineService mock;
protected void setUp() throws Exception {
endpoint = new GetFrequentFlyerMileageEndpoint();
control = MockControl.createControl(AirlineService.class);
mock = (AirlineService) control.getMock();
endpoint.setAirlineService(mock);
endpoint.afterPropertiesSet();
}
public void testInvokeInternal() throws Exception {
control.expectAndReturn(mock.getFrequentFlyerMileage(), 42);
control.replay();
Element element = endpoint.invokeInternal(null);
assertNotNull("No element returned", element);
assertEquals("Invalid local name", "GetFrequentFlyerMileageResponse", element.getName());
assertEquals("Invalid namespace", "http://www.springframework.org/spring-ws/samples/airline/schemas",
element.getNamespaceURI());
assertEquals("Invalid result", "42", element.getTextNormalize());
control.verify();
}
}

View File

@@ -0,0 +1,190 @@
/*
* 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.impl;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import junit.framework.TestCase;
import org.easymock.MockControl;
import org.joda.time.DateTime;
import org.joda.time.YearMonthDay;
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 MockControl flightDaoControl;
private FlightDao flightDaoMock;
private MockControl ticketDaoControl;
private TicketDao ticketDaoMock;
private MockControl securityServiceControl;
private FrequentFlyerSecurityService securityServiceMock;
protected void setUp() throws Exception {
airlineService = new AirlineServiceImpl();
flightDaoControl = MockControl.createControl(FlightDao.class);
flightDaoMock = (FlightDao) flightDaoControl.getMock();
airlineService.setFlightDao(flightDaoMock);
ticketDaoControl = MockControl.createControl(TicketDao.class);
ticketDaoMock = (TicketDao) ticketDaoControl.getMock();
airlineService.setTicketDao(ticketDaoMock);
securityServiceControl = MockControl.createControl(FrequentFlyerSecurityService.class);
securityServiceMock = (FrequentFlyerSecurityService) securityServiceControl.getMock();
airlineService.setFrequentFlyerSecurityService(securityServiceMock);
}
protected void tearDown() throws Exception {
flightDaoControl.verify();
ticketDaoControl.verify();
securityServiceControl.verify();
}
public void testBookFlight() throws Exception {
String flightNumber = "AB1234";
DateTime departureTime = new DateTime();
Passenger passenger = new Passenger("John", "Doe");
List passengers = new ArrayList();
passengers.add(passenger);
Flight flight = new Flight();
flight.setNumber(flightNumber);
flight.setSeatsAvailable(10);
flightDaoControl.expectAndReturn(flightDaoMock.getFlight(flightNumber, departureTime), flight);
flightDaoMock.update(flight);
ticketDaoMock.save(null);
ticketDaoControl.setMatcher(MockControl.ALWAYS_MATCHER);
flightDaoControl.replay();
ticketDaoControl.replay();
securityServiceControl.replay();
Ticket 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());
}
public void testBookFlightFrequentFlyer() throws Exception {
String flightNumber = "AB1234";
DateTime departureTime = new DateTime();
FrequentFlyer frequentFlyer = new FrequentFlyer("john", "changeme", "John", "Doe");
List passengers = new ArrayList();
passengers.add(frequentFlyer);
Flight flight = new Flight();
flight.setNumber(flightNumber);
flight.setSeatsAvailable(1);
flight.setMiles(10);
securityServiceControl.expectAndReturn(securityServiceMock.getFrequentFlyer("john"), frequentFlyer);
flightDaoControl.expectAndReturn(flightDaoMock.getFlight(flightNumber, departureTime), flight);
flightDaoMock.update(flight);
ticketDaoMock.save(null);
ticketDaoControl.setMatcher(MockControl.ALWAYS_MATCHER);
flightDaoControl.replay();
ticketDaoControl.replay();
securityServiceControl.replay();
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());
}
public void testBookFlightNoSeatAvailable() throws Exception {
String flightNumber = "AB1234";
DateTime departureTime = new DateTime();
List passengers = Collections.singletonList(new Passenger());
Flight flight = new Flight();
flightDaoControl.expectAndReturn(flightDaoMock.getFlight(flightNumber, departureTime), flight);
flightDaoControl.replay();
ticketDaoControl.replay();
securityServiceControl.replay();
try {
airlineService.bookFlight(flightNumber, departureTime, passengers);
fail("Should have thrown an NoSeatAvailableException");
}
catch (NoSeatAvailableException ex) {
}
}
public void testBookFlightNoSuchFlight() throws Exception {
String flightNumber = "AB1234";
DateTime departureTime = new DateTime();
List passengers = Collections.singletonList(new Passenger());
flightDaoControl.expectAndReturn(flightDaoMock.getFlight(flightNumber, departureTime), null);
flightDaoControl.replay();
ticketDaoControl.replay();
securityServiceControl.replay();
try {
airlineService.bookFlight(flightNumber, departureTime, passengers);
fail("Should have thrown an NoSuchFlightException");
}
catch (NoSuchFlightException ex) {
}
}
public void testGetFlights() throws Exception {
String toCode = "to";
String fromCode = "from";
YearMonthDay departureDate = new YearMonthDay(2006, 1, 31);
Flight flight = new Flight();
List flights = new ArrayList();
flights.add(flight);
DateTime startOfPeriod = new DateTime(2006, 1, 31, 0, 0, 0, 0);
DateTime endOfPeriod = new DateTime(2006, 2, 1, 0, 0, 0, 0);
flightDaoControl.expectAndReturn(
flightDaoMock.findFlights(fromCode, toCode, startOfPeriod, endOfPeriod, ServiceClass.ECONOMY), flights);
flightDaoControl.replay();
ticketDaoControl.replay();
securityServiceControl.replay();
List result = airlineService.getFlights(fromCode, toCode, departureDate, ServiceClass.ECONOMY);
assertEquals("Invalid result", flights, result);
}
public void testGetFlightsDefaultServiceClass() throws Exception {
String toCode = "to";
String fromCode = "from";
YearMonthDay departureDate = new YearMonthDay(2006, 1, 31);
Flight flight = new Flight();
List flights = new ArrayList();
flights.add(flight);
DateTime startOfPeriod = new DateTime(2006, 1, 31, 0, 0, 0, 0);
DateTime endOfPeriod = new DateTime(2006, 2, 1, 0, 0, 0, 0);
flightDaoControl.expectAndReturn(
flightDaoMock.findFlights(fromCode, toCode, startOfPeriod, endOfPeriod, ServiceClass.ECONOMY), flights);
flightDaoControl.replay();
ticketDaoControl.replay();
securityServiceControl.replay();
List result = airlineService.getFlights(fromCode, toCode, departureDate, null);
assertEquals("Invalid result", flights, result);
}
}

View File

@@ -0,0 +1,116 @@
/*
* 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.ws;
import java.util.Collections;
import java.util.List;
import org.custommonkey.xmlunit.XMLTestCase;
import org.custommonkey.xmlunit.XMLUnit;
import org.easymock.MockControl;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.YearMonthDay;
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.Passenger;
import org.springframework.ws.samples.airline.domain.ServiceClass;
import org.springframework.ws.samples.airline.domain.Ticket;
import org.springframework.ws.samples.airline.service.AirlineService;
public class BookFlightEndpointTest extends XMLTestCase {
private BookFlightEndpoint endpoint;
private MockControl serviceControl;
private AirlineService serviceMock;
private DateTime departure;
private Ticket ticket;
private Document responseDocument;
private SAXBuilder saxBuilder;
protected void setUp() throws Exception {
XMLUnit.setIgnoreWhitespace(true);
endpoint = new BookFlightEndpoint();
serviceControl = MockControl.createControl(AirlineService.class);
serviceMock = (AirlineService) serviceControl.getMock();
endpoint.setAirlineService(serviceMock);
endpoint.afterPropertiesSet();
saxBuilder = new SAXBuilder();
responseDocument = saxBuilder.build(getClass().getResourceAsStream("bookFlightResponse.xml"));
departure = new DateTime(2006, 1, 1, 0, 0, 0, 0, DateTimeZone.UTC);
DateTime arrival = new DateTime(2006, 2, 2, 0, 0, 0, 0, DateTimeZone.UTC);
Flight flight = new Flight();
flight.setNumber("EF1234");
flight.setDepartureTime(departure);
flight.setArrivalTime(arrival);
Airport from = new Airport("ABC", "Airport", "City");
Airport to = new Airport("DEF", "Airport", "City");
flight.setFrom(from);
flight.setTo(to);
flight.setServiceClass(ServiceClass.ECONOMY);
ticket = new Ticket();
ticket.setId(new Long(42));
ticket.setFlight(flight);
ticket.setIssueDate(new YearMonthDay(2006, 1, 1));
}
public void testInvoke() throws Exception {
Passenger passenger = new Passenger("John", "Doe");
List passengers = Collections.singletonList(passenger);
ticket.addPassenger(passenger);
serviceControl.expectAndReturn(serviceMock.bookFlight("EF1234", departure, passengers), ticket);
serviceControl.replay();
Document requestDocument = saxBuilder.build(getClass().getResourceAsStream("bookFlightRequest.xml"));
Element result = endpoint.invokeInternal(requestDocument.getRootElement());
assertNotNull("Invalid result", result);
Document resultDocument = new Document();
resultDocument.setRootElement(result);
XMLOutputter outputter = new XMLOutputter();
assertXMLEqual(outputter.outputString(responseDocument), outputter.outputString(resultDocument));
serviceControl.verify();
}
public void testInvokeFrequentFlyer() throws Exception {
FrequentFlyer frequentFlyer = new FrequentFlyer("john", "changeme", "John", "Doe");
List passengers = Collections.singletonList(frequentFlyer);
ticket.addPassenger(frequentFlyer);
serviceControl.expectAndReturn(serviceMock.bookFlight("EF1234", departure, passengers), ticket);
serviceControl.replay();
Document requestDocument =
saxBuilder.build(getClass().getResourceAsStream("bookFlightRequestFrequentFlyer.xml"));
Element result = endpoint.invokeInternal(requestDocument.getRootElement());
assertNotNull("Invalid result", result);
Document resultDocument = new Document();
resultDocument.setRootElement(result);
XMLOutputter outputter = new XMLOutputter();
assertXMLEqual(outputter.outputString(responseDocument), outputter.outputString(resultDocument));
serviceControl.verify();
}
}

View File

@@ -0,0 +1,75 @@
/*
* 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.ws;
import java.util.ArrayList;
import java.util.List;
import junit.framework.TestCase;
import org.easymock.MockControl;
import org.joda.time.DateTime;
import org.joda.time.YearMonthDay;
import org.springframework.ws.samples.airline.domain.Flight;
import org.springframework.ws.samples.airline.schema.GetFlightsRequest;
import org.springframework.ws.samples.airline.schema.GetFlightsResponse;
import org.springframework.ws.samples.airline.schema.ServiceClass;
import org.springframework.ws.samples.airline.schema.impl.GetFlightsRequestImpl;
import org.springframework.ws.samples.airline.service.AirlineService;
public class GetFlightsEndpointTest extends TestCase {
private GetFlightsEndpoint endpoint;
private MockControl serviceControl;
private AirlineService serviceMock;
protected void setUp() throws Exception {
endpoint = new GetFlightsEndpoint();
serviceControl = MockControl.createControl(AirlineService.class);
serviceMock = (AirlineService) serviceControl.getMock();
endpoint.setAirlineService(serviceMock);
}
public void testInvoke() throws Exception {
String fromAirportCode = "ABC";
String toAirportCode = "DEF";
YearMonthDay departureDate = new YearMonthDay();
GetFlightsRequest request = new GetFlightsRequestImpl();
request.setFrom(fromAirportCode);
request.setTo(toAirportCode);
request.setDepartureDate(departureDate.toDateTimeAtMidnight().toGregorianCalendar());
request.setServiceClass(ServiceClass.FIRST);
List flights = new ArrayList();
Flight flight = new Flight();
flight.setNumber("1");
flight.setDepartureTime(new DateTime());
flight.setArrivalTime(new DateTime());
flights.add(flight);
serviceControl.expectAndReturn(serviceMock.getFlights(fromAirportCode, toAirportCode, departureDate,
org.springframework.ws.samples.airline.domain.ServiceClass.FIRST), flights);
serviceControl.replay();
GetFlightsResponse response = (GetFlightsResponse) endpoint.invokeInternal(request);
serviceControl.verify();
assertNotNull("Response is null", response);
assertEquals("Invalid amount of flights in response", 1, response.getFlight().size());
org.springframework.ws.samples.airline.schema.Flight responseFlight =
(org.springframework.ws.samples.airline.schema.Flight) response.getFlight().get(0);
assertEquals("Invalid flight number on flight", "1", responseFlight.getNumber());
}
}