/*
 * Copyright (c) 2002, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package signatureejb;

import java.io.Serializable;
import java.rmi.RemoteException;
import jakarta.ejb.SessionBean;
import jakarta.ejb.SessionContext;
import jakarta.ejb.EJBException;
import javax.naming.*;
import javax.xml.rpc.handler.MessageContext;
import java.util.Date;

public class SignatureEJB implements SessionBean {
    private SessionContext sc;

    private java.util.Date date;
    private MyDateValueType myDate;
    private MyDateValueType[] myDates;

    public SignatureEJB(){}

    public void ejbCreate() throws RemoteException {
        System.out.println("In SignatureEJB::ejbCreate !!");
    }

    public void SetTestDate(java.util.Date testDate) {
        System.out.println("In SignatureEJB::setTestDate = " + testDate);
        date = testDate;
    }

    public java.util.Date GetTestDate() {
        System.out.println("In SignatureEJB::getTestDate !!");
        return date;
    }

    public void setMyDateValueType(MyDateValueType mytestdate) {
        System.out.println("In SignatureEJB::setMyDateValueType: date = "
            + mytestdate.getDate() + " ; whine = " + mytestdate.getWhine());
        myDate = mytestdate;
    }

    public MyDateValueType getMyDateValueType() {
        System.out.println("In SignatureEJB::getMyDateValueType !!");
        return myDate;
    }

    public void setMyDateValueTypes(MyDateValueType[] mytestdates) {
        System.out.println("In SignatureEJB::setMyDateValueTypes: dates.size = "
            + mytestdates.length);
        myDates = mytestdates;
    }

    public MyDateValueType[] getMyDateValueTypes() {
        System.out.println("In SignatureEJB::getMyDateValueTypes !!");
        return myDates;
    }

    public String SayHello(String msg) {
        System.out.println("In SignatureEJB::SayHello !!");
        return "Hello! " + msg;
    }

    public void setSessionContext(SessionContext sc) {
        this.sc = sc;
    }

    public void ejbRemove() throws RemoteException {}

    public void ejbActivate() {}

    public void ejbPassivate() {}
}
