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,22 @@
<?xml version="1.0"?>
<project name="spring-oxm-maven2-targets" default="generate-sources">
<property name="schema" value="${basedir}/src/main/webapp/airline.xsd"/>
<property name="generate.target.directory" value="${basedir}/target/generated-sources/main/java"/>
<target name="generate-sources">
<mkdir dir="${generate.target.directory}"/>
<taskdef name="xjc" classname="com.sun.tools.xjc.XJCTask"
classpathref="maven.runtime.classpath"/>
<xjc target="${generate.target.directory}"
package="org.springframework.ws.samples.airline.schema"
schema="${schema}">
<produces dir="${generate.target.directory}" includes="**/*.java"/>
</xjc>
<copy todir="${basedir}/target/classes">
<fileset dir="${generate.target.directory}">
<exclude name="**/*.java"/>
</fileset>
</copy>
</target>
</project>

View File

@@ -0,0 +1,3 @@
target:
wsdl -namespace:Spring.Ws.Samples.Airline.Client.CSharp -out:src/AirlineService.cs ../../src/main/webapp/airline.wsdl
mcs -out:bin/airline.exe -r:System.Web.Services src/main.cs src/AirlineService.cs

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,4 @@
@echo off
set WSE_PATH="C:\Program Files\Microsoft WSE\v2.0"
%WSE_PATH%\Tools\Wsdl\WseWsdl2 ..\..\src\main\webapp\airline.wsdl src\AirlineService-wse.cs
csc -nologo -out:bin\getmileage.exe -reference:%WSE_PATH%\Microsoft.Web.Services2.dll src\wse.cs src\AirlineService-wse.cs

View File

@@ -0,0 +1,3 @@
set WSE_PATH="C:\Program Files\Microsoft WSE\v2.0"
%WSE_PATH%\Tools\Wsdl\WseWsdl2 ..\..\src\main\webapp\airline.wsdl src\AirlineService-wse.cs
csc -out:bin\airline-wse.exe -reference:%WSE_PATH%\Microsoft.Web.Services2.dll src\wse.cs src\AirlineService-wse.cs

View File

@@ -0,0 +1,2 @@
wsdl -out:src\AirlineService.cs ..\..\src\webapp\airline.wsdl ..\..\src\webapp\airline.xsd
csc -out:bin\airline.exe src\main.cs src\AirlineService.cse.csosoft WSE\v2.0\Microsoft.Web.Services2.dll" -define:WSE src\main.cs src\AirlineService.cs

View File

@@ -0,0 +1,20 @@
SPRING WEB SERVICES
This directory contains two C# clients for the Airline Web Service. One sample (airline.exe) uses non-secure
functionality, and works under both .NET and Mono, while getmileage.exe only works under .NET because it relies on
Microsoft's Web Services enhancements (WSE 2.0) to perform WS-Security.
The C# client is executable: just run the executable file and (if the war file is deployed at the default
http://localhost:8080/airline) the web service will be called, causing a flight reservations to be created.
If the web service is NOT running at the default URL, you can append the URL argument to the exectuable file
(e.g. 'airline.exe http://localhost:8080/airline-webservice/Airline').
C# Client Sample table of contents
---------------------------------------------------
* bin - The executable files for the clients: airline.exe and getmileage.exe
* src - The source files for the clients.
* Makefile - Mono makefile.
* build.bat - .NET build batch file for airline.exe
* build-getmileage.bat - .NET build batch file for getmileage.exe

View File

@@ -0,0 +1,78 @@
//------------------------------------------------------------------------------
// <autogenerated>
// This code was generated by a tool.
// Runtime Version: 1.1.4322.2032
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </autogenerated>
//------------------------------------------------------------------------------
//
// InfoVersionComment, WseWsdl2, Version=2.0.3.0, Culture=neutral, PublicKeyToken=26ba029e599ec4f8, RunTime Version: 1.1.4322.2032
//
using System;
using System.Xml;
using Microsoft.Web.Services2;
using Microsoft.Web.Services2.Addressing;
using Microsoft.Web.Services2.Messaging;
using System.Xml.Serialization;
[SoapService("http://www.springframework.org/spring-ws/samples/airline/definitions")]
public class AirlineService : SoapClient
{
public AirlineService() : base( new Uri("http://localhost:8080/airline/Airline") )
{
}
[SoapMethod("http://www.springframework.org/spring-ws/samples/airline/GetFlights")]
public SoapEnvelope GetFlights( SoapEnvelope request )
{
return base.SendRequestResponse("GetFlights", request);
}
public IAsyncResult BeginGetFlights( SoapEnvelope request, System.AsyncCallback callback, object asyncState)
{
return base.BeginSendRequestResponse("GetFlights", request, callback, asyncState);
}
public SoapEnvelope EndGetFlights( System.IAsyncResult asyncResult )
{
return base.EndSendRequestResponse(asyncResult);
}
[SoapMethod("http://www.springframework.org/spring-ws/samples/airline/BookFlight")]
public SoapEnvelope BookFlight( SoapEnvelope request )
{
return base.SendRequestResponse("BookFlight", request);
}
public IAsyncResult BeginBookFlight( SoapEnvelope request, System.AsyncCallback callback, object asyncState)
{
return base.BeginSendRequestResponse("BookFlight", request, callback, asyncState);
}
public SoapEnvelope EndBookFlight( System.IAsyncResult asyncResult )
{
return base.EndSendRequestResponse(asyncResult);
}
[SoapMethod("http://www.springframework.org/spring-ws/samples/airline/GetFrequentFlyerMileage")]
public SoapEnvelope GetFrequentFlyerMileage( SoapEnvelope request )
{
return base.SendRequestResponse("GetFrequentFlyerMileage", request);
}
public IAsyncResult BeginGetFrequentFlyerMileage( SoapEnvelope request, System.AsyncCallback callback, object asyncState)
{
return base.BeginSendRequestResponse("GetFrequentFlyerMileage", request, callback, asyncState);
}
public SoapEnvelope EndGetFrequentFlyerMileage( System.IAsyncResult asyncResult )
{
return base.EndSendRequestResponse(asyncResult);
}
}

View File

@@ -0,0 +1,204 @@
// ------------------------------------------------------------------------------
// <autogenerated>
// This code was generated by a tool.
// Mono Runtime Version: 1.1.4322.2032
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </autogenerated>
// ------------------------------------------------------------------------------
//
// This source code was auto-generated by Mono Web Services Description Language Utility
//
namespace Spring.Ws.Samples.Airline.Client.CSharp {
/// <remarks/>
[System.Web.Services.WebServiceBinding(Name="AirlinePort", Namespace="http://www.springframework.org/spring-ws/samples/airline/definitions")]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
public class AirlineService : System.Web.Services.Protocols.SoapHttpClientProtocol {
public AirlineService() {
this.Url = "http://localhost:8080/airline/Airline";
}
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://www.springframework.org/spring-ws/samples/airline/GetFlights", ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Bare, Use=System.Web.Services.Description.SoapBindingUse.Literal)]
[return: System.Xml.Serialization.XmlArray(ElementName="GetFlightsResponse", Namespace="http://www.springframework.org/spring-ws/samples/airline/schemas")]
[return: System.Xml.Serialization.XmlArrayItem(ElementName="flight", IsNullable=false)]
public Flight[] GetFlights([System.Xml.Serialization.XmlElement(Namespace="http://www.springframework.org/spring-ws/samples/airline/schemas")] MessageGetFlightsRequest GetFlightsRequest) {
object[] results = this.Invoke("GetFlights", new object[] {
GetFlightsRequest});
return ((Flight[])(results[0]));
}
public System.IAsyncResult BeginGetFlights(MessageGetFlightsRequest GetFlightsRequest, System.AsyncCallback callback, object asyncState) {
return this.BeginInvoke("GetFlights", new object[] {
GetFlightsRequest}, callback, asyncState);
}
public Flight[] EndGetFlights(System.IAsyncResult asyncResult) {
object[] results = this.EndInvoke(asyncResult);
return ((Flight[])(results[0]));
}
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://www.springframework.org/spring-ws/samples/airline/BookFlight", ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Bare, Use=System.Web.Services.Description.SoapBindingUse.Literal)]
[return: System.Xml.Serialization.XmlElement("BookFlightResponse", Namespace="http://www.springframework.org/spring-ws/samples/airline/schemas")]
public Ticket BookFlight([System.Xml.Serialization.XmlElement(Namespace="http://www.springframework.org/spring-ws/samples/airline/schemas")] MessageBookFlightRequest BookFlightRequest) {
object[] results = this.Invoke("BookFlight", new object[] {
BookFlightRequest});
return ((Ticket)(results[0]));
}
public System.IAsyncResult BeginBookFlight(MessageBookFlightRequest BookFlightRequest, System.AsyncCallback callback, object asyncState) {
return this.BeginInvoke("BookFlight", new object[] {
BookFlightRequest}, callback, asyncState);
}
public Ticket EndBookFlight(System.IAsyncResult asyncResult) {
object[] results = this.EndInvoke(asyncResult);
return ((Ticket)(results[0]));
}
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://www.springframework.org/spring-ws/samples/airline/GetFrequentFlyerMileage", ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Bare, Use=System.Web.Services.Description.SoapBindingUse.Literal)]
[return: System.Xml.Serialization.XmlElement("GetFrequentFlyerMileageResponse", Namespace="http://www.springframework.org/spring-ws/samples/airline/schemas")]
public int GetFrequentFlyerMileage([System.Xml.Serialization.XmlElement(Namespace="http://www.springframework.org/spring-ws/samples/airline/schemas")] object GetFrequentFlyerMileageRequest) {
object[] results = this.Invoke("GetFrequentFlyerMileage", new object[] {
GetFrequentFlyerMileageRequest});
return ((int)(results[0]));
}
public System.IAsyncResult BeginGetFrequentFlyerMileage(object GetFrequentFlyerMileageRequest, System.AsyncCallback callback, object asyncState) {
return this.BeginInvoke("GetFrequentFlyerMileage", new object[] {
GetFrequentFlyerMileageRequest}, callback, asyncState);
}
public int EndGetFrequentFlyerMileage(System.IAsyncResult asyncResult) {
object[] results = this.EndInvoke(asyncResult);
return ((int)(results[0]));
}
}
/// <remarks/>
[System.Xml.Serialization.XmlType(Namespace="http://www.springframework.org/spring-ws/samples/airline/schemas")]
[System.Xml.Serialization.XmlRoot("GetFlightsRequest", Namespace="http://www.springframework.org/spring-ws/samples/airline/schemas")]
public class MessageGetFlightsRequest {
/// <remarks/>
public string from;
/// <remarks/>
public string to;
/// <remarks/>
[System.Xml.Serialization.XmlElement(DataType="date")]
public System.DateTime departureDate;
/// <remarks/>
public ServiceClass serviceClass;
/// <remarks/>
[System.Xml.Serialization.XmlIgnore()]
public bool serviceClassSpecified;
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://www.springframework.org/spring-ws/samples/airline/schemas")]
public enum ServiceClass {
/// <remarks/>
economy,
/// <remarks/>
business,
/// <remarks/>
first,
}
/// <remarks/>
[System.Xml.Serialization.XmlType(Namespace="http://www.springframework.org/spring-ws/samples/airline/schemas")]
public class Flight {
/// <remarks/>
public string number;
/// <remarks/>
public System.DateTime departureTime;
/// <remarks/>
public Airport from;
/// <remarks/>
public System.DateTime arrivalTime;
/// <remarks/>
public Airport to;
/// <remarks/>
public ServiceClass serviceClass;
}
/// <remarks/>
[System.Xml.Serialization.XmlType(Namespace="http://www.springframework.org/spring-ws/samples/airline/schemas")]
public class Airport {
/// <remarks/>
public string code;
/// <remarks/>
public string name;
/// <remarks/>
public string city;
}
/// <remarks/>
[System.Xml.Serialization.XmlType(Namespace="http://www.springframework.org/spring-ws/samples/airline/schemas")]
[System.Xml.Serialization.XmlRoot("BookFlightRequest", Namespace="http://www.springframework.org/spring-ws/samples/airline/schemas")]
public class MessageBookFlightRequest {
/// <remarks/>
public string flightNumber;
/// <remarks/>
public System.DateTime departureTime;
/// <remarks/>
[System.Xml.Serialization.XmlArrayItem(ElementName="passenger", Type=typeof(Name), IsNullable=false)]
[System.Xml.Serialization.XmlArrayItem(ElementName="username", Type=typeof(string), IsNullable=false)]
public object[] passengers;
}
/// <remarks/>
[System.Xml.Serialization.XmlType(Namespace="http://www.springframework.org/spring-ws/samples/airline/schemas")]
public class Name {
/// <remarks/>
public string first;
/// <remarks/>
public string last;
}
/// <remarks/>
[System.Xml.Serialization.XmlType(Namespace="http://www.springframework.org/spring-ws/samples/airline/schemas")]
[System.Xml.Serialization.XmlRoot("BookFlightResponse", Namespace="http://www.springframework.org/spring-ws/samples/airline/schemas")]
public class Ticket {
/// <remarks/>
public long id;
/// <remarks/>
[System.Xml.Serialization.XmlElement(DataType="date")]
public System.DateTime issueDate;
/// <remarks/>
[System.Xml.Serialization.XmlArrayItem(ElementName="passenger", IsNullable=false)]
public Name[] passengers;
/// <remarks/>
public Flight flight;
}
}

View File

@@ -0,0 +1,66 @@
using System;
using System.Web;
using System.Web.Services.Protocols;
namespace Spring.Ws.Samples.Airline.Client.CSharp {
public class Client {
public static void Main(string[] args) {
try {
AirlineService service = new AirlineService();
if (args.Length > 0) {
service.Url = args[0];
} else {
service.Url = "http://localhost:8080/airline/Airline";
}
// Get all flights on 31st Januari, 2006 from Amsterdam to Venice
MessageGetFlightsRequest getFlightsRequest = new MessageGetFlightsRequest();
getFlightsRequest.from = "AMS";
getFlightsRequest.to = "VCE";
getFlightsRequest.departureDate = new DateTime(2006,1,31);
Console.WriteLine("Requesting flights on {0:d}", getFlightsRequest.departureDate);
Flight[] flights = service.GetFlights(getFlightsRequest);
Console.WriteLine("Got {0} results", flights.Length);
if (flights.Length > 0) {
// Book the first flight using John Doe as a frequent flyer
MessageBookFlightRequest bookFlightRequest = new MessageBookFlightRequest();
bookFlightRequest.flightNumber = flights[0].number;
bookFlightRequest.departureTime = flights[0].departureTime;
bookFlightRequest.passengers = new object[] { "john" };
Ticket ticket = service.BookFlight(bookFlightRequest);
WriteTicket(ticket);
}
} catch (SoapException ex) {
Console.Error.WriteLine("SOAP Fault Code {0}", ex.Code);
Console.Error.WriteLine("SOAP Fault String: {0}", ex.Message);
}
}
private static void WriteTicket(Ticket ticket) {
Console.WriteLine("Ticket {0}", ticket.id);
Console.WriteLine("Ticket issue date:\t{0:d}", ticket.issueDate);
foreach (Name passenger in ticket.passengers) {
WriteName(passenger);
}
WriteFlight(ticket.flight);
}
private static void WriteName(Name name) {
Console.WriteLine("Passenger Name:");
Console.WriteLine("{0} {1}", name.first, name.last);
Console.WriteLine("------------");
}
private static void WriteFlight(Flight flight) {
Console.WriteLine("{0:d}", flight.departureTime);
Console.WriteLine("{0}\t{1}", flight.number, flight.serviceClass);
Console.WriteLine("------------");
Console.WriteLine("Depart:\t{0}-{1}\t{2:t}", flight.from.code, flight.from.name,
flight.departureTime);
Console.WriteLine("\t{0}", flight.from.city);
Console.WriteLine("Arrive:\t{0}-{1}\t{2:t}", flight.to.code, flight.to.name,
flight.arrivalTime);
Console.WriteLine("\t{0}", flight.to.city);
}
}
}

View File

@@ -0,0 +1,32 @@
using System;
using System.Web;
using System.Web.Services.Protocols;
using System.Xml;
using Microsoft.Web.Services2;
using Microsoft.Web.Services2.Security;
using Microsoft.Web.Services2.Security.Tokens;
namespace Spring.Ws.Samples.Airline.Client.CSharp {
public class Client {
public static void Main(string[] args) {
try {
AirlineService service = new AirlineService();
if (args.Length > 0) {
service.Destination = new Uri(args[0]);
}
SoapEnvelope request = new SoapEnvelope();
request.SetBodyObject(@"<GetFrequentFlyerMileage xmlns=""http://www.springframework.org/spring-ws/samples/airline/schemas""/>");
UsernameToken userToken = new UsernameToken("john","changeme", PasswordOption.SendHashed);
request.Context.Security.Tokens.Add(userToken);
SoapEnvelope response = service.GetFrequentFlyerMileage(request);
int miles = XmlConvert.ToInt32(response.Body.FirstChild.InnerText);
Console.Out.WriteLine("'john' has {0} frequent flyer miles", miles);
} catch (SoapException ex) {
Console.Error.WriteLine("SOAP Fault Code {0}", ex.Code);
Console.Error.WriteLine("SOAP Fault String: {0}", ex.Message);
}
}
}
}

View File

@@ -0,0 +1,6 @@
SPRING WEB SERVICES
Client table of contents
---------------------------------------------------
* cs - A client for the airline service written in C#.
* saaj - Two clients that are written in Java and use SAAJ.

View File

@@ -0,0 +1,59 @@
<?xml version="1.0"?>
<project name="spring-ws-airline-sample-saaj-client" default="build">
<property name="bin.dir" value="bin"/>
<property name="src.dir" value="src"/>
<target name="build">
<mkdir dir="${bin.dir}"/>
<javac srcdir="${src.dir}" destdir="${bin.dir}">
<classpath>
<pathelement location="lib/saaj-api.jar"/>
<pathelement location="lib/xws-security.jar"/>
</classpath>
</javac>
<copy todir="${bin.dir}">
<fileset dir="${src.dir}">
<exclude name="**/*.java"/>
</fileset>
</copy>
</target>
<target name="clean">
<delete dir="${bin.dir}"/>
</target>
<target name="run" depends="getflights,getmileage"/>
<target name="getflights" depends="build">
<java classname="org.springframework.ws.samples.airline.client.saaj.GetFlights" fork="true" failonerror="true">
<classpath>
<pathelement location="${bin.dir}"/>
<pathelement location="lib/saaj-api.jar"/>
<pathelement location="lib/saaj-impl.jar"/>
<pathelement location="lib/mail.jar"/>
<pathelement location="lib/activation.jar"/>
<pathelement location="lib/xercesImpl.jar"/>
</classpath>
</java>
</target>
<target name="getmileage" depends="build">
<java classname="org.springframework.ws.samples.airline.client.saaj.GetFrequentFlyerMileage" fork="true"
failonerror="true">
<classpath>
<pathelement location="${bin.dir}"/>
<pathelement location="lib/saaj-api.jar"/>
<pathelement location="lib/saaj-impl.jar"/>
<pathelement location="lib/mail.jar"/>
<pathelement location="lib/activation.jar"/>
<pathelement location="lib/xercesImpl.jar"/>
<pathelement location="lib/xws-security.jar"/>
<pathelement location="lib/xmldsig.jar"/>
<pathelement location="lib/xmlsec.jar"/>
</classpath>
<arg value="john"/>
<arg value="changeme"/>
</java>
</target>
</project>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

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

View File

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

View File

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

View File

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

172
samples/airline/pom.xml Normal file
View File

@@ -0,0 +1,172 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>spring-ws-samples</artifactId>
<groupId>org.springframework.ws</groupId>
<version>1.0-m3-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>airline</artifactId>
<packaging>war</packaging>
<name>Spring WS Airline Sample</name>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>generate-sources</phase>
<configuration>
<tasks>
<ant antfile="${basedir}/build-maven2.xml" inheritRefs="true">
<target name="generate-sources" />
</ant>
</tasks>
<sourceRoot>${project.build.directory}/generated-sources/main/java</sourceRoot>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<!-- Spring-WS dependencies -->
<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-ws-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-oxm</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-ws-security</artifactId>
</dependency>
<!-- Spring dependencies -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-hibernate</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-mock</artifactId>
</dependency>
<!-- XML handling dependencies -->
<dependency>
<groupId>jdom</groupId>
<artifactId>jdom</artifactId>
</dependency>
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<exclusions>
<exclusion>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
</exclusion>
<exclusion>
<groupId>jdom</groupId>
<artifactId>jdom</artifactId>
</exclusion>
<exclusion>
<groupId>xerces</groupId>
<artifactId>xmlParserAPIs</artifactId>
</exclusion>
<exclusion>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
</exclusion>
<exclusion>
<groupId>xom</groupId>
<artifactId>xom</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>xalan</groupId>
<artifactId>xalan</artifactId>
<scope>test</scope>
</dependency>
<!-- O/X Mapping dependencies -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>1.0.6</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-libs</artifactId>
<version>1.0.6</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-xjc</artifactId>
<version>1.0.6</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.sun.msv.datatype.xsd</groupId>
<artifactId>xsdlib</artifactId>
<version>20060615</version>
<scope>compile</scope>
</dependency>
<!-- DAO dependencies -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>3.1.3</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.2.1</version>
<exclusions>
<exclusion>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
</exclusion>
<exclusion>
<groupId>xerces</groupId>
<artifactId>xerces</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>3.1.11</version>
</dependency>
<dependency>
<groupId>hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>1.8.0.4</version>
<scope>test</scope>
</dependency>
<!-- Various dependencies -->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time-hibernate</artifactId>
<version>0.8</version>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,32 @@
=====================================================
== Spring Web Service Airline sample application ==
=====================================================
1. INTRODUCTION
Features a web service on top of an airline reservation system, backed by a database. The web service works by using XML
Marshalling techniques (JAXB 1), and JDOM in combination with XPath queries to pull information from a message. All
messages follow following the airline.xsd schema in src/webapp.
A C# client is available in the client directory.
2. INSTALLATION
The Airline sample is a normal web application that connects to a database of your choice.
1. Create a database using one of the scripts in src/etc/db. First, initialize the database using either the MySQL or
PostgreSQL initDB.sql script, and after that run populateDb.sql.
2. Adjust the jdbc.properties in src/main/resources/org/springframework/ws/samples/airline/dao
to reflect your database connection settings
3. Adjust the hibernate.properties in src/main/resources/org/springframework/ws/samples/airline/dao/hibernate
4. run "mvn package" and deploy the war file generated in target; or run "mvn jetty:run" to run the sample
using the Jetty Web container built into Maven 2.
Note that both MySQL drivers are linked in using Maven so you don't have include these in your server if you're using
this database.
3. THE CLIENTS
The client directory contains two sample clients: one in C# and one using SAAJ. More instructions are provided in the
readme files in the directories.

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());
}
}

View File

@@ -0,0 +1,35 @@
<?xml version="1.0"?>
<project name="spring-ws-airline-sample-saaj-client" default="build">
<property name="bin.dir" value="bin"/>
<property name="src.dir" value="src"/>
<target name="build">
<mkdir dir="${bin.dir}"/>
<javac srcdir="${src.dir}" destdir="${bin.dir}">
<classpath>
<pathelement location="lib/saaj-api.jar"/>
</classpath>
</javac>
</target>
<target name="clean">
<delete dir="${bin.dir}"/>
</target>
<target name="run" depends="echo"/>
<target name="echo" depends="build">
<java classname="org.springframework.ws.samples.echo.client.saaj.EchoClient" fork="true" failonerror="true">
<classpath>
<pathelement location="${bin.dir}"/>
<pathelement location="lib/saaj-api.jar"/>
<pathelement location="lib/saaj-impl.jar"/>
<pathelement location="lib/mail.jar"/>
<pathelement location="lib/activation.jar"/>
<pathelement location="lib/xercesImpl.jar"/>
</classpath>
</java>
</target>
</project>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,10 @@
SPRING WEB SERVICES
This directory contains a Java clients for the Echo Web Service that uses SAAJ: SOAP with Attachments API for Java. It
creates a SOAP message for the 'echo' operation, and sends it using SAAJ. This client does not use Spring-WS in any way.
SAJA Client Sample table of contents
---------------------------------------------------
* src - The source files for the client
* build.xml - Ant build file with a 'build' and a 'run' target

View File

@@ -0,0 +1,101 @@
/*
* 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.echo.client.saaj;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.Name;
import javax.xml.soap.SOAPBodyElement;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFault;
import javax.xml.soap.SOAPMessage;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
/**
* A client for the Echo Web Service that uses SAAJ.
*
* @author Ben Ethridge
* @author Arjen Poutsma
*/
public class EchoClient {
public static final String NAMESPACE_URI = "http://www.springframework.org/spring-ws/samples/echo";
public static final String PREFIX = "tns";
private SOAPConnectionFactory connectionFactory;
private MessageFactory messageFactory;
private URL url;
public EchoClient(String url) throws SOAPException, MalformedURLException {
connectionFactory = SOAPConnectionFactory.newInstance();
messageFactory = MessageFactory.newInstance();
this.url = new URL(url);
}
private SOAPMessage createEchoRequest() throws SOAPException {
SOAPMessage message = messageFactory.createMessage();
SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();
Name echoRequestName = envelope.createName("echoRequest", PREFIX, NAMESPACE_URI);
SOAPBodyElement echoRequestElement = message.getSOAPBody()
.addBodyElement(echoRequestName);
echoRequestElement.setValue("Hello");
return message;
}
public void callWebService() throws SOAPException, IOException {
SOAPMessage request = createEchoRequest();
SOAPConnection connection = connectionFactory.createConnection();
SOAPMessage response = connection.call(request, url);
if (!response.getSOAPBody().hasFault()) {
writeEchoResponse(response);
}
else {
SOAPFault fault = response.getSOAPBody().getFault();
System.err.println("Received SOAP Fault");
System.err.println("SOAP Fault Code :" + fault.getFaultCode());
System.err.println("SOAP Fault String :" + fault.getFaultString());
}
}
private void writeEchoResponse(SOAPMessage message) throws SOAPException {
SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();
Name echoResponseName = envelope.createName("echoResponse", PREFIX, NAMESPACE_URI);
SOAPBodyElement echoResponseElement = (SOAPBodyElement) message
.getSOAPBody().getChildElements(echoResponseName).next();
String echoValue = echoResponseElement.getTextContent();
System.out.println("Echo Response [" + echoValue + "]");
}
public static void main(String[] args) throws Exception {
String url = "http://localhost:8080/echo/services";
if (args.length > 0) {
url = args[0];
}
EchoClient echoClient = new EchoClient(url);
echoClient.callWebService();
}
}

18
samples/echo/pom.xml Normal file
View File

@@ -0,0 +1,18 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>spring-ws-samples</artifactId>
<groupId>org.springframework.ws</groupId>
<version>1.0-m3-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>echo</artifactId>
<packaging>war</packaging>
<name>Spring WS Echo Sample</name>
<dependencies>
<!-- Spring-WS dependencies -->
<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-ws-core</artifactId>
</dependency>
</dependencies>
</project>

13
samples/echo/readme.txt Normal file
View File

@@ -0,0 +1,13 @@
=====================================================
== Spring Web Service Echo sample application ==
=====================================================
1. INTRODUCTION
This sample shows a bare-bones echoing service. Incoming messages are handled via DOM, and a simple 'business logic'
service is used to obtain the result.
2. INSTALLATION
Simply run "mvn package" and deploy the war file generated in target

View File

@@ -0,0 +1,16 @@
log4j.rootCategory=WARN, stdout, logfile
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=${@PROJECT_NAME@.root}/@PROJECT_NAME@.log
log4j.appender.logfile.MaxFileSize=512KB
# Keep three backup files
log4j.appender.logfile.MaxBackupIndex=3
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
#Pattern to output : date priority [category] - <message>line_separator
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - <%m>%n

View File

@@ -0,0 +1,33 @@
/*
* 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.echo.service;
/**
* Defines the "business logic" of the web service.
*
* @author Ingo Siebert
* @author Arjen Poutsma
*/
public interface EchoService {
/**
* Returns the given string.
*
* @return <code>s</code>
*/
String echo(String s);
}

View File

@@ -0,0 +1,32 @@
/*
* 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.echo.service.impl;
import org.springframework.ws.samples.echo.service.EchoService;
/**
* Default implementation of <code>EchoService</code>.
*
* @author Ingo Siebert
* @author Arjen Poutsma
*/
public class EchoServiceImpl implements EchoService {
public String echo(String s) {
return s;
}
}

View File

@@ -0,0 +1,89 @@
/*
* 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.echo.ws;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.springframework.util.Assert;
import org.springframework.ws.endpoint.AbstractDomPayloadEndpoint;
import org.springframework.ws.samples.echo.service.EchoService;
/**
* Simple echoing Web service endpoint. Uses a <code>EchoService</code> to create a response string.
*
* @author Ingo Siebert
* @author Arjen Poutsma
*/
public class EchoEndpoint extends AbstractDomPayloadEndpoint {
/**
* Namespace of both request and response.
*/
public static final String NAMESPACE_URI = "http://www.springframework.org/spring-ws/samples/echo";
/**
* The local name of the expected request.
*/
public static final String ECHO_REQUEST_LOCAL_NAME = "echoRequest";
/**
* The local name of the created response.
*/
public static final String ECHO_RESPONSE_LOCAL_NAME = "echoResponse";
private EchoService echoService;
/**
* Sets the "business service" to delegate to.
*/
public void setEchoService(EchoService echoService) {
this.echoService = echoService;
}
/**
* Reads the given <code>requestElement</code>, and sends a the response back.
*
* @param requestElement the contents of the SOAP message as DOM elements
* @param document a DOM document to be used for constructing <code>Node</code>s
* @return the response element
*/
protected Element invokeInternal(Element requestElement, Document document) throws Exception {
Assert.isTrue(NAMESPACE_URI.equals(requestElement.getNamespaceURI()), "Invalid namespace");
Assert.isTrue(ECHO_REQUEST_LOCAL_NAME.equals(requestElement.getLocalName()), "Invalid local name");
NodeList children = requestElement.getChildNodes();
Text requestText = null;
for (int i = 0; i < children.getLength(); i++) {
if (children.item(i).getNodeType() == Node.TEXT_NODE) {
requestText = (Text) children.item(i);
break;
}
}
if (requestText == null) {
throw new IllegalArgumentException("Could not find request text node");
}
String echo = echoService.echo(requestText.getNodeValue());
Element responseElement = document.createElementNS(NAMESPACE_URI, ECHO_RESPONSE_LOCAL_NAME);
Text responseText = document.createTextNode(echo);
responseElement.appendChild(responseText);
return responseElement;
}
}

View File

@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- Spring-WS beans -->
<bean id="messageDispatcher" class="org.springframework.ws.soap.SoapMessageDispatcher">
<description>
The MessageDispatcher is responsible for routing messages to endpoints.</description>
<property name="endpointMappings" ref="payloadMapping"/>
<property name="endpointExceptionResolvers" ref="endpointExceptionResolver"/>
</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. Every message is passed to the default endpoint. Additionally, messages are logged
using the logging interceptor.</description>
<property name="defaultEndpoint" ref="echoEndpoint"/>
<property name="interceptors">
<list>
<ref local="validatingInterceptor"/>
<ref local="loggingInterceptor"/>
</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 'echo.xsd' XML
Schema file.</description>
<property name="schema" value="/echo.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="echoEndpoint" class="org.springframework.ws.samples.echo.ws.EchoEndpoint">
<description>
This endpoint handles echo requests.</description>
<property name="echoService" ref="echoService"/>
</bean>
<bean id="echoWsdl" class="org.springframework.ws.wsdl.wsdl11.SimpleWsdl11Definition">
<property name="wsdl" value="/echo.wsdl"/>
</bean>
<bean id="endpointExceptionResolver" class="org.springframework.ws.soap.endpoint.SimpleSoapExceptionResolver"/>
<!-- "Business" (POJO) services -->
<bean id="echoService" class="org.springframework.ws.samples.echo.service.impl.EchoServiceImpl"/>
</beans>

View File

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

View File

@@ -0,0 +1,32 @@
<?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="messageEndpointHandlerAdapter"
class="org.springframework.ws.transport.http.MessageEndpointHandlerAdapter">
<description>
This handler adapter makes sure that Spring's DispatcherServlet supports MessageEndpoint instances as
handlers. It uses a SAAJ to construct SoapMessageContexts (and SoapMessages).</description>
<property name="messageContextFactory">
<bean class="org.springframework.ws.soap.saaj.SaajSoapMessageContextFactory"/>
</property>
</bean>
<bean id="wsdlDefinitionHandlerAdapter" class="org.springframework.ws.transport.http.WsdlDefinitionHandlerAdapter">
<description>
This handler adapter adds support for WsdlDefinitions to Spring's DispatcherServlet. It transforms location
attributes in the original WSDL to reflect the URL of the incoming HTTP request.</description>
<property name="transformLocations" value="true"/>
</bean>
<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"/>
<property name="mappings">
<props>
<prop key="/services/*">messageDispatcher</prop>
<prop key="echo.wsdl">echoWsdl</prop>
</props>
</property>
</bean>
</beans>

View File

@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>
"Echo" WebService</display-name>
<description>Returns a given string(only A-Z and a-z chars allowed). See echo.xsd file.</description>
<!--Location of the Log4J config file, for initialization and refresh checks.
Applied by Log4jConfigListener. -->
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/log4j.properties</param-value>
</context-param>
<!-- Logger for web server specific messages. -->
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<!-- Loads the root application context of this web app at startup.
Use WebApplicationContextUtils.getWebApplicationContext(servletContext)
to access it anywhere in the web application, outside of the framework.
The root context is the parent of all servlet-specific contexts.
This means that its beans are automatically available in these child contexts,
both for getBean(name) calls and (external) bean references. -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Starts the web service servlet. -->
<servlet>
<servlet-name>springws</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<!-- We map all service request to the springws servlet. -->
<servlet-mapping>
<servlet-name>springws</servlet-name>
<url-pattern>/services</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>springws</servlet-name>
<url-pattern>*.wsdl</url-pattern>
</servlet-mapping>
<mime-mapping>
<extension>xsd</extension>
<mime-type>text/xml</mime-type>
</mime-mapping>
</web-app>

Some files were not shown because too many files have changed in this diff Show More