/**
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 -
 - JASS: Java Advanced tranSaction Support
 -
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 -
 - This module was originally developed by 
 -
 -    LSD (Distributed Systems Lab, http://lsd.ls.fi.upm.es/lsd/lsd.htm)
 -    at Universidad Politecnica de Madrid (UPM) as an ObjectWeb Consortium
 -    (http://www.objectweb.org) project.
 -
 -    This project has been partially funded by the European Commission under
 -    the IST programme of V FP grant IST-2001-37126 and by the Spanish
 -    Ministry of Science & Technology (MCyT) grants TIC2002-10376-E and
 -    TIC2001-1586-C03-02
 -
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 -  The original code and portions created by LSD are 
 -  Copyright (c) 2004 LSD (UPM)  
 -  All rights reserved.
 -  
 - Redistribution and use in source and binary forms, with or without 
 - modification, are permitted provided that the following conditions are met:
 -
 - -Redistributions of source code must retain the above copyright notice, this
 - list of conditions and the following disclaimer. 
 -
 - -Redistributions in binary form must reproduce the above copyright notice, 
 - this list of conditions and the following disclaimer in the documentation 
 - and/or other materials provided with the distribution. 
 -
 - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
 - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
 - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
 - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
 - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
 - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
 - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
 - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
 - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 - POSSIBILITY OF SUCH DAMAGE.
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 -
 -  Author: Francisco Perez Sorrosal (frperezs)
 -
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/

package org.objectweb.jass.examples.travelagency.ejbs;

import java.rmi.RemoteException;
import java.sql.SQLException;

import javax.activity.opennested.UserOpenNested;
import javax.ejb.CreateException;
import javax.ejb.EJBException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import org
	.objectweb
	.jass
	.examples
	.travelagency
	.exceptions
	.NotEnoughRoomsException;
import org
	.objectweb
	.jass
	.examples
	.travelagency
	.exceptions
	.NotEnoughSeatsException;

/**
 * Makes the composed reservation by invoking the Airline and Hotel EJBs.
 * It creates a ONT activity that scopes both invocations through the
 * OpenNested service. 
 * @author fran
 * Date: Feb 16, 2004
 * org.objectweb.jass.examples.travelagency.ejbsTravelAgencyBean.java
 */
public class TravelAgencyBean implements SessionBean {
	private AirlineHome airlineHome;
	private Airline airline;
	private HotelHome hotelHome;
	private Hotel hotel;
	private UserOpenNested uon;

	public void ejbCreate() throws javax.ejb.CreateException {
	}

	public void ejbActivate() throws EJBException {
	}

	public void ejbPassivate() throws EJBException {
	}

	public void ejbRemove() throws EJBException {
	}

	public void setSessionContext(SessionContext sessionContext)
		throws EJBException {
	}

	/**
	 *	Creates a ONT activity and invokes the Airline and the Hotel EJBs.
	 * If is not possible to make any reservation, the activity is rolled back
	 * and an exception is thrown to the application that uses this EJB. 
	 * @param name - not used.
	 * @param nSeats - number of seats to reserve.
	 * @param nRooms - number of rooms to reserve.
	 * @throws NotEnoughSeatsException - thrown if there are not enough seats.
	 * @throws NotEnoughRoomsException - thrown if there are not enough rooms.
	 */
	public void makeReservation(String name, int nSeats, int nRooms)
		throws Exception {

		Airline airline = getAdaptAirlineEJB();
		Hotel hotel = getAdaptHotelEJB();
		UserOpenNested uon = getUserOpenNested();
		
		try {
			uon.activityBegin(0);
			try {
				airline.reserveSeats(nSeats);
				hotel.reserveRooms(nRooms);
				uon.activityCommit(null);
			} catch (RemoteException e) {
				e.printStackTrace();
			} catch (NotEnoughSeatsException e) {
				uon.activityRollback();
				throw e;
			} catch (NotEnoughRoomsException e) {
				uon.activityRollback();
				throw e;
			} catch (SQLException e) {
				uon.activityRollback();
				throw e;
			}
		} catch (Exception e) {
			throw e;
		}
	}

	/**
	 * Gets the reference to the UserOpenNested service.
	 */
	private UserOpenNested getUserOpenNested() {
		Context ctx = null;

		try {
			ctx = new InitialContext();
			uon = (UserOpenNested) ctx.lookup("UserOpenNested");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return uon;
	}

	/**
	 * Gets the reference to the Airline EJB.
	 */
	private Airline getAdaptAirlineEJB() {
		Object obj = null;
		Context ctx = null;
		try {
			ctx = new InitialContext();
			obj = ctx.lookup("AirlineEJB");
			airlineHome =
				(AirlineHome) javax.rmi.PortableRemoteObject.narrow(
					obj,
					AirlineHome.class);
			airline = airlineHome.create();
		} catch (NamingException e) {
			e.printStackTrace();
		} catch (CreateException e) {
			e.printStackTrace();
		} catch (RemoteException e) {
			e.printStackTrace();
		}
		return airline;
	}

	/**
	 * Gets the reference to the Hotel EJB.
	 */
	private Hotel getAdaptHotelEJB() {
		Object obj = null;
		Context ctx = null;
		try {
			ctx = new InitialContext();
			obj = ctx.lookup("HotelEJB");
			hotelHome =
				(HotelHome) javax.rmi.PortableRemoteObject.narrow(
					obj,
					HotelHome.class);
			hotel = hotelHome.create();
		} catch (NamingException e) {
			e.printStackTrace();
		} catch (CreateException e) {
			e.printStackTrace();
		} catch (RemoteException e) {
			e.printStackTrace();
		}
		return hotel;
	}

}
