// Copyright 2012 Citrix Systems, Inc. Licensed under the
// Apache License, Version 2.0 (the "License"); you may not use this
// file except in compliance with the License.  Citrix Systems, Inc.
// reserves all rights not expressly granted by 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.
// 
// Automatically generated by addcopyright.py at 04/03/2012
package com.cloud.vm;

import com.cloud.domain.Domain;
import com.cloud.domain.dao.DomainDao;
import com.cloud.user.Account;
import com.cloud.user.User;
import com.cloud.user.dao.AccountDao;
import com.cloud.user.dao.UserDao;
import com.cloud.utils.Journal;

public class ReservationContextImpl implements ReservationContext {
    User _caller;
    Account _account;
    Domain _domain;
    Journal _journal;
    String _reservationId;
    
    public ReservationContextImpl(String reservationId, Journal journal, User caller) {
        this(reservationId, journal, caller, null, null);
    }
    
    public ReservationContextImpl(String reservationId, Journal journal, User caller, Account account) {
        this(reservationId, journal, caller, account, null);
        
    }
    
    public ReservationContextImpl(String reservationId, Journal journal, User caller, Account account, Domain domain) {
        _caller = caller;
        _account = account;
        _domain = domain;
        _journal = journal;
        _reservationId = reservationId;
    }
    
    @Override
    public long getDomainId() {
        return 0;
    }

    @Override
    public long getAccountId() {
        return _caller.getAccountId();
    }

    @Override
    public User getCaller() {
        return _caller;
    }

    @Override
    public Account getAccount() {
        if (_account == null) {
            _account = s_accountDao.findByIdIncludingRemoved(_caller.getId());
        }
        return _account; 
    }

    @Override
    public Domain getDomain() {
        if (_domain == null) {
            getAccount();
            _domain = s_domainDao.findByIdIncludingRemoved(_account.getDomainId());
        }
        return _domain;
    }

    @Override
    public Journal getJournal() {
        return _journal;
    }

    @Override
    public String getReservationId() {
        return _reservationId;
    }
    
    static UserDao s_userDao;
    static DomainDao s_domainDao;
    static AccountDao s_accountDao;
    
    static public void setComponents(UserDao userDao, DomainDao domainDao, AccountDao accountDao) {
        s_userDao = userDao;
        s_domainDao = domainDao;
        s_accountDao = accountDao;
    }
}
