package ossj.common.ex;

import com.infomodel.MplsVpnServiceKeyImpl;
import com.infomodel.MplsVpnServiceValue;
import com.infomodel.MplsVpnServiceValueImpl;
import com.infomodel.MplsVpnServiceValueIterator;
import com.infomodel.MplsVpnServiceValueIteratorImpl;
import java.util.Collection;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import javax.ejb.CreateException;
import javax.ejb.EJBException;
import javax.ejb.FinderException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.oss.ApplicationContext;
import javax.oss.EventPropertyDescriptor;
import javax.oss.ManagedEntityKey;
import javax.oss.ManagedEntityValue;
import javax.oss.NamedQueryResponse;
import javax.oss.NamedQueryValue;
import javax.oss.UpdateProcedureResponse;
import javax.oss.UpdateProcedureValue;
import javax.oss.cbe.service.ServiceState;
import ossj.common.ApplicationContextImpl;



/**
 * This is the bean class for the VpnServiceBean enterprise bean.
 * Created Jul 5, 2006 10:00:29 AM
 * @author vince
 */
public class VpnServiceBean implements SessionBean, VpnServiceRemoteBusiness {
    
    private static final Map MANAGED_EVENT_DESCRIPTOR_MAP;
    static {
        MANAGED_EVENT_DESCRIPTOR_MAP = new java.util.HashMap();
        
        MANAGED_EVENT_DESCRIPTOR_MAP.put(MplsVpnCreateEvent.class.getName(),
                new MplsVpnCreateEventPropertyDescriptorImpl());
    }
    
    
    private JmsSender myJmsSender;
    private ApplicationContext myApplicationContext;
    private String myApplicationDN;
    
    private SessionContext context;
    private InitialContext ctx = null;
    private Context getContext(){
        try {
            if (ctx == null)
                ctx = new InitialContext();
        } catch (NamingException e) {
            throw new EJBException("Get a Naming exception at new InitialContext"+e.getExplanation());
        }
        return ctx;
    }
    
    private MplsvpnTblLocalHome getEntityHome(){
        MplsvpnTblLocalHome home = null;
        String myEntityName = "java:comp/env/ejb/MplsvpnTbl";
        
        try {
            // or java:comp/env/ejb/MplsvpnTbl or ejb/MplsvpnTbl (use of the <ejb-ref-name>ejb/MplsvpnTbl</ejb-ref-name> from DD)???
            // use the jndi-name from sun-ejb-jar.xml
            System.out.println("try: "+myEntityName+"\n");
            return (MplsvpnTblLocalHome) getContext().lookup(myEntityName);
            
        } catch (NamingException e) {
            System.out.println("fail: "+myEntityName+":\n"+e.getExplanation());
            throw new EJBException("Get a Naming exception at lookup for ["+myEntityName+"]: " +e.getExplanation());
        }
    }
    
    // <editor-fold defaultstate="collapsed" desc="EJB infrastructure methods. Click the + sign on the left to edit the code.">
    // TODO Add code to acquire and use other enterprise resources (DataSource, JMS, enterprise bean, Web services)
    // TODO Add business methods or web service operations
    /**
     * @see javax.ejb.SessionBean#setSessionContext(javax.ejb.SessionContext)
     */
    public void setSessionContext(SessionContext aContext) {
        context = aContext;
    }
    
    /**
     * @see javax.ejb.SessionBean#ejbActivate()
     */
    public void ejbActivate() {
        
    }
    
    /**
     * @see javax.ejb.SessionBean#ejbPassivate()
     */
    public void ejbPassivate() {
        
    }
    
    /**
     * @see javax.ejb.SessionBean#ejbRemove()
     */
    public void ejbRemove() {
        
    }
    // </editor-fold>
    
    /**
     * See section 7.10.3 of the EJB 2.0 specification
     * See section 7.11.3 of the EJB 2.1 specification
     */
    public void ejbCreate() {
        // TODO implement ejbCreate if necessary, acquire resources
        // This method has access to the JNDI context so resource aquisition
        // spanning all methods can be performed here such as home interfaces
        // and data sources.
        
    }
    
    // my service interface
    /**
     * Create a Value Type object for a specific MplsVpnService type.
     *<p>
     * Not to be confused with the creation of a MplsVpnService.
     *<p>
     * The Session Bean is used as a factory for the creation of Value types.
     *
     * @param valueType The fully qualified type of the MplsVpnServiceValue to be created.
     * @exception javax.oss.OssIllegalArgumentException Invalid Arguments
     * @exception java.rmi.RemoteException           System Level Exception
     */
    
    public com.infomodel.MplsVpnServiceValue makeMplsVpnServiceValue(String valueType)
    throws javax.oss.OssIllegalArgumentException,
            java.rmi.RemoteException{
        return (MplsVpnServiceValue) makeManagedEntityValue(valueType);
    }
    
    
    /**
     *    This is the createMplsVpnServiceByValue
     *
     *    This method is MANDATORY
     *    @param mplsVpnServiceValue
     *    @return com.infomodel.MplsVpnServiceKey
     *
     *    @throws javax.oss.OssIllegalArgumentException
     *    @throws java.rmi.RemoteException
     *    @throws javax.ejb.DuplicateKeyException
     *    @throws javax.ejb.CreateException
     */
    public com.infomodel.MplsVpnServiceKey  createMplsVpnServiceByValue(
            com.infomodel.MplsVpnServiceValue mplsVpnServiceValue)
            throws javax.oss.OssIllegalArgumentException,
            java.rmi.RemoteException,
            javax.ejb.DuplicateKeyException,
            javax.ejb.CreateException{
        // build the key...
        MplsVpnServiceKeyImpl key = new MplsVpnServiceKeyImpl();
        key.setType(MplsVpnServiceKeyImpl.class.getName());
        key.setPrimaryKey(new String()+System.currentTimeMillis());
        
        // create the entity
        /*    public ossj.common.ex.MplsvpnTblLocal create(
         java.lang.String mplskey,
         java.lang.String state,
         java.lang.String subscriberid,
         java.lang.Integer mandatory,
         java.lang.String vrfname,
         java.lang.Integer startmode) throws javax.ejb.CreateException;
         
         */
        
        getEntityHome().create((String)key.getPrimaryKey(),
                (mplsVpnServiceValue.isPopulated(MplsVpnServiceValue.STATE)?mplsVpnServiceValue.getState():ServiceState.ACTIVE),
                (mplsVpnServiceValue.isPopulated(MplsVpnServiceValue.SUBSCRIBER_ID)?mplsVpnServiceValue.getSubscriberId():null),
                (mplsVpnServiceValue.isPopulated(MplsVpnServiceValue.MANDATORY)?(mplsVpnServiceValue.isMandatory()?1:0):0),
                (mplsVpnServiceValue.isPopulated(MplsVpnServiceValue.VRF_NAME)?mplsVpnServiceValue.getVrfName():null),
                (mplsVpnServiceValue.isPopulated(MplsVpnServiceValue.START_MODE)?mplsVpnServiceValue.getStartMode():0)
                );
        
        MplsVpnCreateEventImpl evt = new MplsVpnCreateEventImpl(getApplicationDN());
        getJmsSender().publish(evt, MplsVpnCreateEvent.class.getName(), mplsVpnServiceValue);
        
        return key;
        
    }
    
    /**
     *    This is the getMplsVpnServiceByKey
     *
     *    This method is MANDATORY
     *    @param mplsVpnServiceKey
     *    @param attrNames
     *    @return com.infomodel.MplsVpnServiceValue
     *
     *    @throws javax.oss.OssIllegalArgumentException
     *    @throws java.rmi.RemoteException
     *    @throws javax.ejb.ObjectNotFoundException
     */
    public com.infomodel.MplsVpnServiceValue  getMplsVpnServiceByKey(
            com.infomodel.MplsVpnServiceKey mplsVpnServiceKey,
            String[] attrNames)
            throws javax.oss.OssIllegalArgumentException,
            java.rmi.RemoteException,
            javax.ejb.ObjectNotFoundException{
        //
        int n = 0;
        String[] attList = null;
        
        try {
            Collection vpn = getEntityHome().findByMplskey((String)mplsVpnServiceKey.getPrimaryKey());
            n = vpn.size();
            if (n > 0){
                // get at leas one element and hope only one
                for (Iterator it = vpn.iterator(); it.hasNext();) {
                    MplsvpnTblLocal myVpn = (MplsvpnTblLocal) it.next();
                    MplsVpnServiceValueImpl myValue = new MplsVpnServiceValueImpl();
                    if (attrNames == null || attrNames.length ==0)
                        attList = myValue.getAttributeNames();
                    else
                        attList = attrNames;
                    
                    for (int i = attList.length -1; i >= 0; i--) {
                        if (MplsVpnServiceValue.STATE.equals(attList[i])) {
                            System.out.println("VPgetMplsVpnServiceByKey state="+myVpn.getState());
                            myValue.setState(myVpn.getState());
                        } else if (MplsVpnServiceValue.SUBSCRIBER_ID.equals(attList[i])){
                            System.out.println("VPgetMplsVpnServiceByKey getSubscriberid="+myVpn.getSubscriberid());
                            myValue.setSubscriberId(myVpn.getSubscriberid());
                        } else if (MplsVpnServiceValue.MANDATORY.equals(attList[i])) {
                            System.out.println("VPgetMplsVpnServiceByKey getMandatory="+myVpn.getMandatory());
                            myValue.setMandatory(myVpn.getMandatory()==0?false:true);
                        } else if (MplsVpnServiceValue.VRF_NAME.equals(attList[i])) {
                            System.out.println("VPgetMplsVpnServiceByKey getVrfname="+myVpn.getVrfname());
                            myValue.setVrfName(myVpn.getVrfname());
                        } else if (MplsVpnServiceValue.START_MODE.equals(attList[i])) {
                            System.out.println("VPgetMplsVpnServiceByKey getStartmode="+myVpn.getStartmode());
                            myValue.setStartMode(myVpn.getStartmode());
                        }
                    }
                    myValue.setMplsVpnServiceKey(mplsVpnServiceKey);
                    // take the first one...
                    return myValue;
                }
            }
        } catch (FinderException fex){
            throw new javax.ejb.ObjectNotFoundException("Finder Exception for key:["+mplsVpnServiceKey.getPrimaryKey()+"] not found in DB\n"+fex.getMessage());
            
        }
        throw new javax.ejb.ObjectNotFoundException("key:["+mplsVpnServiceKey.getPrimaryKey()+"] not found in DB, size = "+n);
    }
    
    /**
     *    This is the setMplsVpnServiceByValue
     *
     *    This method is MANDATORY
     *    @param mplsVpnServiceValue
     *    @param resyncRequired
     *    @throws javax.oss.OssIllegalArgumentException
     *    @throws java.rmi.RemoteException
     *    @throws javax.ejb.ObjectNotFoundException
     *    @throws javax.oss.OssSetException
     *    @throws javax.oss.OssResyncRequiredException
     */
    public void  setMplsVpnServiceByValue(com.infomodel.MplsVpnServiceValue mplsVpnServiceValue, boolean resyncRequired)
    throws javax.oss.OssIllegalArgumentException, java.rmi.RemoteException,
            javax.ejb.ObjectNotFoundException, javax.oss.OssSetException,
            javax.oss.OssResyncRequiredException{
        
        String pk = (String) mplsVpnServiceValue.getMplsVpnServiceKey().getPrimaryKey();
        if (pk == null){
            throw new javax.oss.OssIllegalArgumentException("Invalid Key field in Value, null primaryKey");
        }
        
        try {
            Collection vpn = getEntityHome().findByMplskey(pk);
            if (vpn.size()>0){
                // get at leas one element and hope only one
                for (Iterator it = vpn.iterator(); it.hasNext();) {
                    MplsvpnTblLocal myVpn = (MplsvpnTblLocal) it.next();
                    String[] attrNames = mplsVpnServiceValue.getPopulatedAttributeNames();
                    for (int i = attrNames.length -1; i >= 0; i--) {
                        if (MplsVpnServiceValue.STATE.equals(attrNames[i])){
                            System.out.println("VPsetMplsVpnServiceByValue getStartmode="+mplsVpnServiceValue.getState());
                            myVpn.setState(mplsVpnServiceValue.getState());
                            
                        } else if (MplsVpnServiceValue.SUBSCRIBER_ID.equals(attrNames[i])){
                            System.out.println("VPsetMplsVpnServiceByValue getStartmode="+mplsVpnServiceValue.getSubscriberId());
                            myVpn.setSubscriberid(mplsVpnServiceValue.getSubscriberId());
                            
                        } else if (MplsVpnServiceValue.MANDATORY.equals(attrNames[i])){
                            System.out.println("VPsetMplsVpnServiceByValue getStartmode="+mplsVpnServiceValue.isMandatory());
                            myVpn.setMandatory(mplsVpnServiceValue.isMandatory()?1:0);
                            
                        } else if (MplsVpnServiceValue.VRF_NAME.equals(attrNames[i])){
                            System.out.println("VPsetMplsVpnServiceByValue getStartmode="+mplsVpnServiceValue.getVrfName());
                            myVpn.setVrfname(mplsVpnServiceValue.getVrfName());
                            
                        } else if (MplsVpnServiceValue.START_MODE.equals(attrNames[i])){
                            System.out.println("VPsetMplsVpnServiceByValue getStartmode="+mplsVpnServiceValue.getStartMode());
                            myVpn.setStartmode(mplsVpnServiceValue.getStartMode());
                        }
                    }
                    // treat the first one only...
                    return;
                }
            }
        } catch (FinderException fex){
            throw new javax.ejb.ObjectNotFoundException("Finder Exception for key:["+pk+"not found in DB\n"+fex.getMessage());
        }
    }
    
    /**
     *    This is the removeMplsVpnServiceByKey
     *
     *    This method is MANDATORY
     *    @param mplsVpnServiceKey
     *    @throws javax.oss.OssIllegalArgumentException
     *    @throws java.rmi.RemoteException
     *    @throws javax.ejb.ObjectNotFoundException
     *    @throws javax.ejb.RemoveException
     */
    public void  removeMplsVpnServiceByKey(com.infomodel.MplsVpnServiceKey mplsVpnServiceKey)
    throws javax.oss.OssIllegalArgumentException, java.rmi.RemoteException,
            javax.ejb.ObjectNotFoundException, javax.ejb.RemoveException{
        try {
            Collection vpn = getEntityHome().findByMplskey((String)mplsVpnServiceKey.getPrimaryKey());
            if (vpn.size()== 1)
                getEntityHome().remove((String)mplsVpnServiceKey.getPrimaryKey());
            else
                throw new javax.ejb.ObjectNotFoundException("Finder Exception for key:["+mplsVpnServiceKey.getPrimaryKey()+"not found in DB\n");
        } catch (FinderException fex){
            throw new javax.ejb.ObjectNotFoundException("Finder Exception for key:["+mplsVpnServiceKey.getPrimaryKey()+"not found in DB\n"+fex.getMessage());
            
        }
    }
    
    // JVT Session interface
    /**
     * Get the names of the optional operations supported by this JVT
     * Session Bean. The names of the optional operations are defined
     * in the <CODE>JVT&lt;ApplicationType&gt;SessionOptionalOps</CODE> interface as
     * defined by the API.
     *
     *
     * @return String array which contains the names of all the optional
     * operations supported by an implementation of a JVT Session Bean.
     *
     * @exception java.rmi.RemoteException
     */
    public String[] getSupportedOptionalOperations( )
    throws java.rmi.RemoteException {
        return new String[0];
    }
    
    /**
     * Get the Managed Entity types supported by a JVT Session Bean.
     *
     * @return String array which contains the fully qualified names of the leaf
     * node interfaces representing the supported managed entity types.
     * Note that it is not the implementation class name that is returned.
     * @exception java.rmi.RemoteException
     */
    
    public String[] getManagedEntityTypes()
    throws java.rmi.RemoteException {
        System.out.println("return com.infomodel.MplsVpnServiceValueImpl");
        return new String[]{"com.infomodel.MplsVpnServiceValueImpl"};
    }
    
    /**
     * Get the Event Type names supported by the JVT Session Bean
     *
     * @return String array which contains the fully qualified names of the
     * leaf node interfaces representing the supported event types.
     * @exception java.rmi.RemoteException
     */
    public String[] getEventTypes()
    throws java.rmi.RemoteException {
        return new String[]{"ossj.common.ex.MplsVpnCreateEventImpl"};
    }
    
    /**
     * Get the EventPropertyDescriptor associated with an event type name.
     *
     * @param eventType fully qualified name of the leaf node Event interface.
     * @return EventPropertyDescriptor which can be used to discover the
     * filterable properties of the specified event type.
     * @exception javax.oss.OssIllegalArgumentException unknown or unsupported
     * event type.
     * @exception java.rmi.RemoteException
     */
    
    public EventPropertyDescriptor getEventDescriptor(String eventType)
    throws javax.oss.OssIllegalArgumentException , java.rmi.RemoteException{
        if("ossj.common.ex.MplsVpnCreateEventImpl".equals(eventType)){
            return new MplsVpnCreateEventPropertyDescriptorImpl();
        } else {
            throw new javax.oss.OssIllegalArgumentException(eventType+" is not supported.");
        }
    }
    
    
    
    /**
     * Create a Value Type object for a specific Managed Entity type.
     * Not to be confused with the creation of a Managed Entity.
     * The Session Bean is used as a factory for the creation of
     * Value Types.
     *
     * @param valueType fully qualified name of the leaf managed entity value
     * interface.
     * @return managed entity value object of the specified type.
     * @exception javax.oss.OssIllegalArgumentException unknown or unsupported
     * managed entity value type.
     * @exception java.rmi.RemoteException
     */
    
    public ManagedEntityValue makeManagedEntityValue( String valueType)
    throws javax.oss.OssIllegalArgumentException, java.rmi.RemoteException{
        if("com.infomodel.MplsVpnServiceValueImpl".equals(valueType)){
            return new MplsVpnServiceValueImpl();
        } else {
            throw new javax.oss.OssIllegalArgumentException(valueType+" is not supported.");
        }
    }
    
    /**
     * Create a UpdateProcedureValue Instance matching a Update Procedure type name.
     * The Session Bean is used as a factory for the creation of
     * Update Procedure values.
     *
     * @param type fully qualified name of the leaf node UpdateProcedureValue interface.
     * @return Update Procedure value object of the specified type.
     * @exception javax.oss.OssIllegalArgumentException unknown or unsupported
     * Update Procedure type.
     * @exception java.rmi.RemoteException
     */
    public UpdateProcedureValue makeUpdateProcedureValue(String type)
    throws javax.oss.OssIllegalArgumentException ,java.rmi.RemoteException {
        if("ossj.common.ex.ResetAllVrfNamesValueImpl".equals(type)){
            return new ResetAllVrfNamesValueImpl();
        } else {
            throw new javax.oss.OssIllegalArgumentException(type+" is not supported.");
        }
    }
    
    
    
    /**
     * Executes the given update procedure. (null is not a vlid argument for this method)
     *
     * @param updateValue a UpdateProcedureValue object representing the Update Procedure to be performed.
     * @return a UpdateProcedureResponse resulting from the Update Procedure execution.
     * @exception javax.oss.OssIllegalArgumentException unsupported Update Procedure value type.
     * @exception java.rmi.RemoteException
     *
     */
    public javax.oss.UpdateProcedureResponse update( javax.oss.UpdateProcedureValue updateprocedureValue)
    throws javax.oss.OssIllegalArgumentException,
            java.rmi.RemoteException{
        ResetAllVrfNamesValueImpl upv = null;
        
        if (updateprocedureValue == null)
            throw new javax.oss.OssIllegalArgumentException("null is not a valied query value");

        try {
            upv = (ResetAllVrfNamesValueImpl) updateprocedureValue;
        } catch (Exception e) {
            throw new javax.oss.OssIllegalArgumentException(updateprocedureValue+" is not supported.");
        }
        //TODO
        return new ResetAllVrfNamesResponseImpl(UpdateProcedureResponse.DONE);
    }
    
    /**
     * Get the UpdateProcedure type names supported by a JVT Session Bean
     *
     * @return String array which contains the fully qualified names of the leaf
     * node interfaces representing the supported update procedure value types,
     * i.e., interfaces which extend UpdateProcedureValue.
     * @exception java.rmi.RemoteException
     */
    
    public String[] getUpdateProcedureTypes()
    throws java.rmi.RemoteException{
        return new String[] {"ossj.common.ex.ResetAllVrfNamesValueImpl"};
    }
    
    /**
     * Query multiple Entities using a NamedQueryValue. (null is not a vlid argument for this method)
     *
     * @param namedQuery a NamedQueryValue object representing the query.
     * @return a NamedQueryResponse used to extract the results of the query.
     * @exception javax.oss.OssIllegalArgumentException unsupported named query value type.
     * @exception java.rmi.RemoteException
     *
     * @ossj:nillableField name=methodReturnValue value=true
     * @ossj:minOccursField name=methodReturnValue value=0
     * @ossj:minOccursField name=namedQuery value=0
     */
    public NamedQueryResponse query(NamedQueryValue namedQuery)
    throws javax.oss.OssIllegalArgumentException, java.rmi.RemoteException{
        //TODO
        if (namedQuery == null)
            throw new javax.oss.OssIllegalArgumentException("null is not a valied query value");
        
        MplsVpnServiceValueIterator res = new MplsVpnServiceValueIteratorImpl();
        return res;
    }
    
    /**
     * Get the Named Query type names supported by a JVT Session Bean
     *
     * @return String array which contains the fully qualified names of the leaf
     * node interfaces representing the supported named query value types,
     * i.e., interfaces which extend NamedQueryValue.
     * @exception java.rmi.RemoteException
     */
    public String[] getNamedQueryTypes()
    throws java.rmi.RemoteException {
        return new String[] {"ossj.common.ex.AllMplsVpnServicesValueImpl"};
    }
    
    /**
     * Create a NamedQueryValue Instance matching a Named Query type name.
     * The Session Bean is used as a factory for the creation of
     * named query values.
     *
     * @param type fully qualified name of the leaf node NamedQueryValue interface.
     * @return query value object of the specified type.
     * @exception javax.oss.OssIllegalArgumentException unknown or unsupported
     * named query type.
     * @exception java.rmi.RemoteException
     */
    public NamedQueryValue makeNamedQueryValue(String type)
    throws javax.oss.OssIllegalArgumentException,java.rmi.RemoteException{
        if("ossj.common.ex.AllMplsVpnServicesValueImpl".equals(type)){
            return new AllMplsVpnServicesValueImpl();
        } else {
            throw new javax.oss.OssIllegalArgumentException(type+" is not supported.");
        }
    }
    
    //=====================
    // Private methods
    //=====================
    private JmsSender getJmsSender() {
        if (myJmsSender == null) {
            try {
                JmsSenderHome aHome = (JmsSenderHome) getContext().lookup("java:comp/env/ejb/JmsSender");
                myJmsSender = aHome.create();
            } catch (java.rmi.RemoteException re) {
                re.printStackTrace();
            } catch (CreateException ce) {
                ce.printStackTrace();
            } catch (NamingException ne) {
                ne.printStackTrace();
            }
        }
        return myJmsSender;
    }
    
    private ApplicationContext getApplicationContext() {
        if (myApplicationContext == null) {
            myApplicationContext = getmyApplicationContext(getContext());
        }
        return myApplicationContext;
    }
    
    private String getApplicationDN() {
        
        if (myApplicationDN == null) {
            try {
                myApplicationDN = (String) getContext().lookup("java:comp/env/ApplicationDN");
                
            } catch (NamingException ne) {
                ne.printStackTrace();
            }
        }
        
        // System.out.println("hi in application DN" + myApplicationDN);
        return myApplicationDN;
    }
    
    
    /**
     * Creates an ApplicationContext based on the current server configuration
     */
    public ApplicationContextImpl getmyApplicationContext(Context aNamingContext) {
        try {
            Hashtable map = aNamingContext.getEnvironment();
            String factory = (String) map.get(Context.INITIAL_CONTEXT_FACTORY);
            String url = (String) map.get(Context.PROVIDER_URL);
            
            return new ApplicationContextImpl(factory, new java.util.HashMap(), url);
        } catch (NamingException ne) {
            System.out.println(ne.toString());
            return null;
        }
    }
}
