/*
 * $Id: CORBAPackageManager.java,v 1.3 2004/11/10 15:02:48 koppy Exp $
 *
 * Copyright (c) Siemens AG 2008 
 *           (c) Universität Paderborn 2008 
 * Licensed under EUPL 1.1. 
 * 
 * Created on 13.07.2004
 *
 * $Log: CORBAPackageManager.java,v $
 * Revision 1.3  2004/11/10 15:02:48  koppy
 * Projektweite Überarbeitung von Error-Logs, Stacktraces,..
 *
 * Revision 1.2  2004/09/20 10:26:11  koppy
 * +javadoc Dokumentation
 *
 * Revision 1.1  2004/08/30 14:49:56  koppy
 * Initiale Version der Workflow-Komponente
 *
 */
package vkc.workflow.service.corba;

import java.util.ArrayList;
import java.util.List;

import vkc.db.entities.VKCUser;
import vkc.misc.VKCLogManager;
import vkc.workflow.WorkflowException;
import vkc.workflow.model.PackageInfo;
import vkc.workflow.model.ProcessDefinitionInfo;
import vkc.workflow.service.CORBAWorkflowService;
import vkc.workflow.service.VKCWorkflowService;
import vkc.workflow.service.WfMConnection;
import vkc.workflow.service.manager.PackageManager;
import vkc.workflow.util.SharkUtils;
import WfBase.NameValue;
import WorkflowModel.TransitionNotAllowed;
import WorkflowModel.WfProcessMgr;
import WorkflowModel.process_mgr_stateType;
import WorkflowService.AdminMisc;
import WorkflowService.ExecutionAdministration;
import WorkflowService.ExternalPackageInvalid;
import WorkflowService.NotConnected;
import WorkflowService.PackageAdministration;
import WorkflowService.PackageHasActiveProcesses;
import WorkflowService.PackageInUse;
import WorkflowService.PackageInvalid;
import WorkflowService.RepositoryMgr;
import WorkflowService.WfProcessMgrIterator;

/**
 * This class represents the CORBA client version
 * of the package manager.
 * 
 * @author Andreas Koop
 */
public class CORBAPackageManager implements PackageManager {

    private CORBAWorkflowService wfService = null;
    
    public CORBAPackageManager( CORBAWorkflowService wfService ){
        this.wfService = wfService;
    }
    /** 
     * (non-Javadoc)
     * @see vkc.workflow.service.manager.PackageManager#getProcessesToStart(vkc.db.entities.VKCUser, java.lang.String)
     */
    public List getProcessesToStart(VKCUser user, String pkgId) {
        
        ExecutionAdministration ea = null;
        AdminMisc adminMisc = wfService.getShark().getAdminInterface().getAdminMisc();
        try {
            ea = wfService.getShark().getAdminInterface().getExecutionAdministration();
            ea.connect(user.getUser(), user.getClearPassword(), wfService.getEngine(), "");
            adminMisc.connect(user.getUser(), user.getClearPassword(), wfService.getEngine(), "");

            WfProcessMgrIterator wpmgi = ea.get_iterator_processmgr(); 
            wpmgi.set_query_expression("packageId.equals(\""+pkgId+"\")");
            WfProcessMgr[] a=wpmgi.get_next_n_sequence(0);

            List processes = new ArrayList(a.length);

            for (int i = 0; i < a.length; ++i) {
                WfProcessMgr pMgr = a[i];
                
                ProcessDefinitionInfo pInfo = new ProcessDefinitionInfo();
                pInfo.setMgrName(pMgr.name());
                pInfo.setPackageId(adminMisc.getProcessMgrPkgId(pMgr.name()));
                pInfo.setProcessDefId(adminMisc.getProcessMgrProcDefId(pMgr
                        .name()));
                pInfo.setName(adminMisc.getProcessMgrProcDefName(pMgr.name()));
                pInfo.setDescription(pMgr.description());
                pInfo.setCategory(pMgr.category());
                pInfo.setEnabled( pMgr.process_mgr_state().value() == process_mgr_stateType._enabled);
                
                if (VKCWorkflowService.debug) {
                    System.err.println("--------processToStart in pkg " + pkgId);
                    System.err.println(pInfo);
                }
                
                // Falls keine Admin-Rechte und der Workflow deaktiviert ist
                // bekommt ihn der User auch nicht!
                if( !user.hasAdminPrivileges() && !pInfo.isEnabled())
                    continue;
                
                processes.add(pInfo);
            }
            return processes;

        } catch (Exception e) {
            VKCLogManager.errorLog(this, "", e.getMessage(),e);
        } finally {
            SharkUtils.disconnect(ea);
            SharkUtils.disconnect(adminMisc);
        }
        return new ArrayList(0);
    }
    
    /** 
     * (non-Javadoc)
     * @see vkc.workflow.service.manager.PackageManager#openPackage(vkc.workflow.service.WfMConnection, java.lang.String)
     */
    public String openPackage(WfMConnection sConn, String xpdlName) throws WorkflowException{
        PackageAdministration pa = wfService.getShark()
								        .getAdminInterface()
								        .getPackageAdministration();
        
        RepositoryMgr rm = wfService.getShark()
        							.getRepositoryManager();
        
        
        try {
            pa.connect( sConn.getUsername(), sConn.getPassword(), wfService.getEngine(), "");
            rm.connect( sConn.getUsername(), sConn.getPassword(), wfService.getEngine(), "");
            String pkgId = rm.getPackageId(xpdlName);
            
            if (pa.isPackageOpened(pkgId))
                return pkgId;
            
            pa.openPkg(xpdlName);
            return pkgId;
        } catch (PackageInvalid e) {
            throw new WorkflowException( "wf.error.packageInvalid", e);
        } catch (ExternalPackageInvalid e) {
            throw new WorkflowException( "wf.error.externalPackageInvalid", e);
        } catch (Exception e ){
            throw new WorkflowException( "wf.error.notConnected", e);
        } finally {
            SharkUtils.disconnect( pa );
            SharkUtils.disconnect( rm );
        }
    }
    /** 
     * (non-Javadoc)
     * @see vkc.workflow.service.manager.PackageManager#closePackage(vkc.workflow.service.WfMConnection, java.lang.String)
     */
    public void closePackage(WfMConnection sConn, String pkgId) throws WorkflowException {
        
        PackageAdministration pa = wfService.getShark()
		        .getAdminInterface()
		        .getPackageAdministration();
        

        try {
            try {
                pa.connect(sConn.getUsername(), sConn.getPassword(), wfService
                        .getEngine(), "");
                
                pa.closePkg( pkgId );
            } catch (PackageInUse e) {
                throw new WorkflowException( "wf.error.packageInUse", e);
            } catch (PackageHasActiveProcesses e) {
                throw new WorkflowException( "wf.error.packageHasActiveProcesses", e);
            } catch ( Exception e ){
                throw new WorkflowException( "wf.error.notConnected", e);
            }


        } finally {
            SharkUtils.disconnect(pa);
        }
        
    }
    /** 
     * (non-Javadoc)
     * @see vkc.workflow.service.manager.PackageManager#getOpenPackages(vkc.workflow.service.WfMConnection)
     */
    public List getOpenPackages(WfMConnection sConn) throws WorkflowException {
        List l = new ArrayList();
        PackageAdministration pa = wfService.getShark()
								        .getAdminInterface()
								        .getPackageAdministration();
		RepositoryMgr rm = wfService.getShark()
										.getRepositoryManager();

        try {
            pa.connect( sConn.getUsername(), sConn.getPassword(), wfService.getEngine(), "");
            rm.connect( sConn.getUsername(), sConn.getPassword(), wfService.getEngine(), "");
            
            String [] openPkgIds = pa.getOpenedPackageIds();
            NameValue [] pathIdMapping = rm.getPackagePathToIdMapping();

            for (int i = 0; i < openPkgIds.length; i++) {
                String pkgId = openPkgIds[i];
                
                PackageInfo pinfo = new PackageInfo();
                pinfo.setPath( getPath(pkgId, pathIdMapping) );
                pinfo.setPackageId( pkgId );
                pinfo.setOpened( true );
                
                l.add(pinfo);
            }
            
        } catch (Exception e) {
            throw new WorkflowException( "wf.error.notConnected",e);
        }finally {
            SharkUtils.disconnect( pa );
            SharkUtils.disconnect( rm );
        }
        
        return l;
        
    }
    /**
     * @param pkgId
     * @param pathIdMapping
     * @return
     */
    private String getPath(String pkgId, NameValue[] pathIdMapping) {
        
        for (int i = 0; i < pathIdMapping.length; i++) {
            NameValue value = pathIdMapping[i];
            if( pkgId.equals( value.the_value.extract_wstring()))
                return value.the_name;
        }
        
        return null;
    }
    /** 
     * (non-Javadoc)
     * @see vkc.workflow.service.manager.PackageManager#setProcessDefinitionEnabled(vkc.workflow.service.WfMConnection, java.lang.String, boolean)
     */
    public void setProcessDefinitionEnabled(WfMConnection sConn, String pMgrName, boolean enabled) throws WorkflowException {
        ExecutionAdministration ea = wfService.getShark().getAdminInterface().getExecutionAdministration();

        if(VKCWorkflowService.debug){
            System.err.println( "setting state of " + pMgrName );
        }
        
        try {
            ea.connect(sConn.getUsername(), sConn.getPassword(), wfService
                    .getEngine(), "");

            WfProcessMgr a = ea.getProcessMgrByName( pMgrName );
            if( a == null)
                return;
            a.set_process_mgr_state(enabled ? process_mgr_stateType.enabled
                                : process_mgr_stateType.disabled);
        } catch (NotConnected e) {
            throw new WorkflowException("wf.error.notConnected", e);
        } catch (TransitionNotAllowed e) {
            throw new WorkflowException("wf.error.transitionNotAllowed", e);
        } catch (Exception e) {
            throw new WorkflowException("wf.error.general", e);
        } finally {
            SharkUtils.disconnect(ea);
        }

            
        
    }
    /** 
     * (non-Javadoc)
     * @see vkc.workflow.service.manager.PackageManager#setPackageEnabled(vkc.workflow.service.WfMConnection, java.lang.String, boolean)
     */
    public void setPackageEnabled(WfMConnection sConn, String pkgId, boolean enabled) throws WorkflowException {
        ExecutionAdministration ea = wfService.getShark().getAdminInterface().getExecutionAdministration();

        try {
            ea.connect(sConn.getUsername(), sConn.getPassword(), wfService
                    .getEngine(), "");

            WfProcessMgrIterator wpmgi = ea.get_iterator_processmgr();
            wpmgi.set_query_expression("packageId.equals(\"" + pkgId + "\")");
            WfProcessMgr[] a = wpmgi.get_next_n_sequence(0);

            for (int i = 0; i < a.length; ++i) {
                a[i].set_process_mgr_state(enabled ? process_mgr_stateType.enabled
                                : process_mgr_stateType.disabled);
            }
        } catch (NotConnected e) {
            throw new WorkflowException("wf.error.notConnected", e);
        } catch (TransitionNotAllowed e) {
            throw new WorkflowException("wf.error.transitionNotAllowed", e);
        } catch (Exception e) {
            throw new WorkflowException("wf.error.general", e);
        } finally {
            SharkUtils.disconnect(ea);
        }
            
    }
}
