/////////////////////////////////////////////////////////////////////////
//
// © Institute for Software Science, University of Vienna, 2004
//
// Copyright in this software belongs to Institute for Software Science, 
// University of Vienna, Nordbergstrasse 15/C/3, 1090 Vienna, Austria
//
// This software may not be used, sold, licensed, transferred, copied
// or reproduced in whole or in part in any manner or form or in or
// on any media by any person other than in accordance with the terms
// of the Licence Agreement supplied with the software, or otherwise
// without the prior written consent of the copyright owners.
//
// This software is distributed WITHOUT ANY WARRANTY, without even the
// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE, except where stated in the Licence Agreement supplied with
// the software.
//
//	Created By :		Nikolay Terziev
//	Created Date :		2004/04/20
//	Created for Project:	GEMSS
//
////////////////////////////////////////////////////////////////////////
//
// Dependencies: None
//
/////////////////////////////////////////////////////////////////////////
//
//	Last commit info:	$Author: niki $
//					$Date: 2004/07/30 14:01:34 $
//					$Revision: 1.8 $
//
/////////////////////////////////////////////////////////////////////////

package at.ac.univie.iss.descriptors;
 

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.UnmarshalException;
import javax.xml.bind.Marshaller;
 
import java.util.List;
import java.util.Iterator;
import java.util.Calendar;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.logging.Logger;
import java.util.logging.Level;
import javax.xml.transform.stream.StreamSource;

import at.ac.univie.iss.descriptors.app.jaxb.appdesc.*; 
 
    
public class ApplicationDescriptorImpl  implements ApplicationDescriptor {
             
	private static Logger logger = Logger.getLogger("at.ac.univie.iss.descriptors");

    private Config configType = null;
    // private Files inputFilesType;
    // private Files outputFilesType;
    private Application appDsc;
         
    private Unmarshaller unmarshaller = null;
    private Marshaller   marshaller = null;
    private ObjectFactory objFactory = null;
    private JAXBContext jc;
    
    public ApplicationDescriptorImpl()throws Exception {
            
        try { 
            jc = JAXBContext.newInstance("at.ac.univie.iss.descriptors.app.jaxb.appdesc");
                    
            unmarshaller = jc.createUnmarshaller();
            unmarshaller.setValidating(true);

            marshaller = jc.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
            objFactory = new ObjectFactory();
               
            appDsc = objFactory.createApplication();
            
            setInfoName("");
            setWorkingDirectory("");
            setJobScriptParameters("debug");
            setJobScript("");
            setFinishFileName("");
        } catch (JAXBException je) {
        	logger.log(Level.SEVERE, "An error occured while creating a new empty Application Descriptor (see details below)!", je);
            throw new Exception("ApplicationDescriptorImpl(): JAXBException ", je);
        }   
       
    }
   
    public ApplicationDescriptorImpl(String appDesc) throws Exception {
        try {
         
            jc = JAXBContext.newInstance("at.ac.univie.iss.descriptors.app.jaxb.appdesc");
                    
            unmarshaller = jc.createUnmarshaller();
            unmarshaller.setValidating(true);

            marshaller = jc.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

            objFactory = new ObjectFactory(); 
            
            appDsc = (at.ac.univie.iss.descriptors.app.jaxb.appdesc.Application) unmarshaller.unmarshal(
                    new StreamSource(new StringReader(appDesc)));
            
            configType = appDsc.getConfiguration();
     
        } catch (UnmarshalException ue) {  
             
        	logger.log(Level.SEVERE, "An error occured while creating a new Application Descriptor based on a given document string (see details below)!", ue);
            throw new Exception(ue);  

        } catch (JAXBException je) {
            
        	logger.log(Level.SEVERE, "An error occured while creating a new Application Descriptor based on a given document string (see details below)!", je);
            throw new Exception(je);
            
        } catch (Exception e) {

        	logger.log(Level.SEVERE, "An error occured while creating a new Application Descriptor based on a given document string (see details below)!", e);
            throw new Exception(e);
        }  
    }
     
    public ApplicationDescriptorImpl(java.io.File appDescFile) throws Exception {
        
        try {
            if ((appDescFile == null) || !appDescFile.exists()) {
             
                throw new Exception("The  Application descriptor file (" + appDescFile + ") does not exist");
            
            }
         
            jc = JAXBContext.newInstance("at.ac.univie.iss.descriptors.app.jaxb.appdesc");
                    
            unmarshaller = jc.createUnmarshaller();
            unmarshaller.setValidating(true);

            marshaller = jc.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

            objFactory = new ObjectFactory(); 
            
            appDsc = (Application) unmarshaller.unmarshal(new java.io.FileInputStream(appDescFile));
            
            configType = appDsc.getConfiguration();
     
        } catch (UnmarshalException ue) {  
             
        	logger.log(Level.SEVERE, "An error occured while creating a new Application Descriptor based on a given document file (see details below)!", ue);
            throw new Exception(ue);  

        } catch (JAXBException je) {
            
        	logger.log(Level.SEVERE, "An error occured while creating a new Application Descriptor based on a given document file (see details below)!", je);
            throw new Exception(je);
            
        } catch (Exception e) {

        	logger.log(Level.SEVERE, "An error occured while creating a new Application Descriptor based on a given document file (see details below)!", e);
            throw new Exception(e);
        }  
        
    }  
      
    public String getInputFileName() {
        
        if (configType == null) {
            return null;
        }
            
        Files inputFilesType = configType.getInputFiles();
            
        if (inputFilesType != null) {
            
            Iterator iter = inputFilesType.getFile().iterator();
         
            if (iter.hasNext()) {
                FileDesc fileDesc = (FileDesc) iter.next(); 
    
                // only the first one
                return fileDesc.getName();
            }
        }
            
        return null;
    }  
        
    public void setInputFileName(String inputFile) throws Exception {
            
        List  files; 
        Files inputFilesType;

        try {
            if (configType == null) {
                createConfig();
                
            }
                 
            inputFilesType = configType.getInputFiles();
            
            if (inputFilesType == null){
                
                inputFilesType = createFiles();
                configType.setInputFiles(inputFilesType); 
            }    
            
            files = inputFilesType.getFile();
                
            FileDesc fileDesc = objFactory.createFileDesc();
                
            fileDesc.setName(inputFile); 
            files.add(0, fileDesc);
                
        } catch (JAXBException jbe) {

        	logger.log(Level.SEVERE, "An error occured while setting input file name (see details below)!", jbe);
            throw new Exception(jbe);
        }
    }  
       
    public String getOutputFileName() {
        
        if (configType == null) {
            return null;
        }
           
        Files outputFilesType = configType.getOutputFiles();  	
           
        if (outputFilesType != null) {
          
            Iterator iter = outputFilesType.getFile().iterator();
             
            if (iter.hasNext()) {
                FileDesc fileDesc = (FileDesc) iter.next(); 
            
                // only the first one
                return fileDesc.getName();
            }
        }
          
        return null;
    }  
       
    public String[] getOutputFileNames() {
          
        String[] fileNames;
        FileDesc fileDesc;
          
        if (configType == null) {
            return new String[0];
        }
          
        Files outputFilesType = configType.getOutputFiles();  	
           
        if (outputFilesType != null) {
               
            Iterator iter = outputFilesType.getFile().iterator();
            int index = 0;

            fileNames = new String[outputFilesType.getFile().size()];
                
            while (iter.hasNext()) {
                   
                fileDesc = (FileDesc) iter.next(); 
                fileNames[index++] = fileDesc.getName();
                     
            }
            return fileNames;
        }
        return new String[0];
    }
        
    public void setOutputFileName(String outputFile) throws Exception {
        List  files; 
        Files outputFilesType;

        try {
            
             if (configType == null) {
                createConfig(); 
            }
                 
            outputFilesType = configType.getOutputFiles();
            
            if (outputFilesType == null){ 
                outputFilesType = createFiles();
                configType.setOutputFiles(outputFilesType); 
            }    
               
            files = outputFilesType.getFile();
                
            FileDesc fileDesc = objFactory.createFileDesc();
               
            fileDesc.setName(outputFile);
            files.add(0, fileDesc);
               
        } catch (JAXBException je) {

        	logger.log(Level.SEVERE, "An error occured while setting output file name (see details below)!", je);
            throw new Exception(je);
        }
    } 
       
    public String getInfoName() {
            
        if (appDsc == null) {
            return null;
        }
            
        return  appDsc.getInfo().getName();
    }
        
    public void setInfoName(String infoName) throws Exception {
            
        try {
            createInfoType();
               
            ApplicationType.InfoType infoType = appDsc.getInfo();
               
            infoType.setName(infoName);
            
        } catch (JAXBException jbe) {

        	logger.log(Level.SEVERE, "An error occured while setting info file name (see details below)!", jbe);
            throw new Exception(jbe);
        }
    }
        
    public String getWorkingDirectory() {
            
        if (configType == null) {
            return null;
        }
            
        PathInfo pathInfo = configType.getWorkingDirectory();

        if (pathInfo == null) {
            return null;
        } else {
            return  pathInfo.getPath();
        }
    }
        
    public void setWorkingDirectory(String workingDirectory) throws Exception {
            
        try {
            if (configType == null) {
                createConfig();
            }
              
            PathInfo pathInfo = createPathInfo();

            pathInfo.setPath(workingDirectory); 
              
            configType.setWorkingDirectory(pathInfo);
               
            appDsc.setConfiguration(configType);
               
        } catch (JAXBException jbe) {

        	logger.log(Level.SEVERE, "An error occured while setting working dir name (see details below)!", jbe);
            throw new Exception(jbe);
        }
            
    }
      
    public String getJobScriptParameters() {
            
        if (configType == null) {
            return null;
        }
        JobScrParams jobParams = configType.getJobScriptParameters();
            
        if (jobParams == null) {
            return null;
        }
            
        Iterator iter = jobParams.getJobScriptParameter().iterator();
             
        if (iter.hasNext()) {
            JobScrParam jobParam = (JobScrParam) iter.next(); 
        
            // only the first one
            return jobParam.getName();
        }
        return null;
    }
      
    public void setJobScriptParameters(String jobParamName) throws Exception {
        List  jobParam; 
        JobScrParams jobParams;
            
        try {
            if (configType == null) {
                createConfig();
            }
                
            createJobScrParams();
            jobParams = configType.getJobScriptParameters();
                
            jobParam = jobParams.getJobScriptParameter();
                
            JobScrParam jParam = objFactory.createJobScrParam();

            jParam.setName(jobParamName);
                     
            jobParam.add(jParam);
                
        } catch (JAXBException jbe) {

        	logger.log(Level.SEVERE, "An error occured while setting job script parameters (see details below)!", jbe);
            throw new Exception(jbe);
        }
    }
        
    public String getJobScript() {
            
        if (configType == null) {
            return null;
        }
            
        PathInfo pathInfo = configType.getJobScript();  
            
        if (pathInfo == null) { 
            return null;
        } else { 
            return pathInfo.getPath();
        }	  	
 
    }
        
    public void setJobScript(String jobScriptName) throws Exception {
            
        try {
            if (configType == null) {
                createConfig();
            }
              
            PathInfo pathInfo = createPathInfo();

            pathInfo.setPath(jobScriptName); 
              
            configType.setJobScript(pathInfo);
               
            appDsc.setConfiguration(configType);
               
        } catch (JAXBException jbe) {

        	logger.log(Level.SEVERE, "An error occured while setting job script (see details below)!", jbe);
            throw new Exception(jbe);
        }
    }
              
    public String getKillScript() {
            
        if (configType == null) {
            return null;
        }
            
        PathInfo pathInfo = configType.getKillScript();  
            
        if (pathInfo == null) { 
            return null;
        } else { 
            return pathInfo.getPath();
        }	  	
 
    }
        
    public void setKillScript(String killScriptName) throws Exception {
            
        try {
            if (configType == null) {
                createConfig();
            }
              
            PathInfo pathInfo = createPathInfo();

            pathInfo.setPath(killScriptName); 
              
            configType.setKillScript(pathInfo);
               
            appDsc.setConfiguration(configType);
               
        } catch (JAXBException jbe) {

        	logger.log(Level.SEVERE, "An error occured while setting kill script (see details below)!", jbe);
            throw new Exception(jbe);
        }
    }
   
      
    public String getFinishFileName() { 
            
        if (configType == null) {
            return null;
        }
            
        NameInfo nameInfo = configType.getFinishFile();
            
        if (nameInfo == null) {
            return null;
        }
            
        return  nameInfo.getName();
    } 
                         
    public void setFinishFileName(String finishFileName) throws Exception { 
            
        try {
                 
            if (configType == null) {
                createConfig();
            }
              
            NameInfo nameInfo = createNameInfo();

            nameInfo.setName(finishFileName); 
              
            configType.setFinishFile(nameInfo);
               
            appDsc.setConfiguration(configType);
               
        } catch (JAXBException jbe) {

        	logger.log(Level.SEVERE, "An error occured while setting finish file (see details below)!", jbe);
            throw new Exception(jbe);
        }
            
    }
        
    public String getFinishFileDisplayName() { 
            
        if (configType == null) {
            return null;
        }
            
        NameInfo nameInfo = configType.getFinishFile();
            
        if (nameInfo == null) {
            return null;
        }
            
        return  nameInfo.getDisplayName();
             
    }  
        
    public String getFinishFileDescription() { 
            
        if (configType == null) {
            return null;
        }
            
        NameInfo nameInfo = configType.getFinishFile();
            
        if (nameInfo == null) {
            return null;
        }
            
        return  nameInfo.getDescription();
    }      
    
    public String getStatusScript() {
           
        if (configType == null) {
            return null;
        }
           
        StatusInfo statusInfo = configType.getStatusInfo();
            
        if (statusInfo == null) {
            return null;
        }
            
        PathInfo pathInfo = statusInfo.getStatusScript();
            
        if (pathInfo == null) {
            return null;
        } else {
            return  pathInfo.getPath();
        }
            
    }
        
    public void setStatusScript(String statusScript)throws Exception { 
            
        try {
            if (configType == null) {
                createConfig();
            }
              
            StatusInfo statusInfoType = createStatus();
              
            PathInfo pathInfo = createPathInfo();

            pathInfo.setPath(statusScript); 
              
            statusInfoType.setStatusScript(pathInfo);
              
            configType.setStatusInfo(statusInfoType);
              
            appDsc.setConfiguration(configType);
             
        } catch (JAXBException jbe) {

        	logger.log(Level.SEVERE, "An error occured while setting status script (see details below)!", jbe);
            throw new Exception(jbe);
        }
            
    }
        
    public String getStatusFile() {
           
        if (configType == null) {
            return null;
        }
           
        StatusInfo statusInfo = configType.getStatusInfo();
            
        if (statusInfo == null) {
            return null;
        }
            
        NameInfo nameInfo = statusInfo.getStatusFile();
            
        if (nameInfo == null) {
            return null;
        } else {
            return  nameInfo.getName();
        }	  	
 
    }
        
    public void setStatusFile(String statusFileName)throws Exception { 
            
        try {
            if (configType == null) {
                createConfig();
            }
              
            StatusInfo statusInfoType = createStatus();
              
            NameInfo nameInfo = createNameInfo();

            nameInfo.setName(statusFileName); 
              
            statusInfoType.setStatusFile(nameInfo);
              
            configType.setStatusInfo(statusInfoType);
              
            appDsc.setConfiguration(configType);
             
        } catch (JAXBException jbe) {

        	logger.log(Level.SEVERE, "An error occured while setting status file (see details below)!", jbe);
            throw new Exception(jbe);
        }
            
    }

    //-----------------
    // Recovery Section
    //-----------------
   
     public String getRestartScript(){
     
     RecoveryInfo recoveryInfo = appDsc.getRecovery();
        
        if (recoveryInfo == null)
            return null;
                
        PathInfo pathInfo = recoveryInfo.getRestartScript();  
            
        if (pathInfo == null) { 
            return null;
        } else { 
            return pathInfo.getPath();
        }	
     }
    
    
    public void setRestartScript(String restartScriptName) throws Exception{
     try {
            
            RecoveryInfo recoveryInfo = appDsc.getRecovery();
            
            if (recoveryInfo == null) {
                
                recoveryInfo = createRecoveryInfo();
                appDsc.setRecovery(recoveryInfo);
            }
              
            PathInfo pathInfo = createPathInfo();

            pathInfo.setPath(restartScriptName); 
              
            recoveryInfo.setRestartScript(pathInfo);  
               
        } catch (JAXBException jbe) {

        	logger.log(Level.SEVERE, "An error occured while setting restart script (see details below)!", jbe);
            throw new Exception(jbe);
        }
    }
    
    
    public String getCheckpointInputFileName() {
            
         RecoveryInfo recoveryInfo = appDsc.getRecovery();
        
        if (recoveryInfo == null)
            return null;
            
        Files inputFilesType = recoveryInfo.getCheckpointInputFiles();
            
        if (inputFilesType != null) {
            
            Iterator iter = inputFilesType.getFile().iterator();
         
            if (iter.hasNext()) {
                FileDesc fileDesc = (FileDesc) iter.next(); 
    
                // only the first one
                return fileDesc.getName();
            }
        }
            
        return null;
    }  
        
    public void setCheckpointInputFileName(String inputFile) throws Exception {
            
        List  files; 
        Files inputFilesType;
        
        try{
           RecoveryInfo recoveryInfo = appDsc.getRecovery();
            
            if (recoveryInfo == null) {
                
                recoveryInfo = createRecoveryInfo();
                appDsc.setRecovery(recoveryInfo);
            }
                
            inputFilesType = recoveryInfo.getCheckpointInputFiles();
            
            if (inputFilesType == null){
                
                inputFilesType = createFiles();
                recoveryInfo.setCheckpointInputFiles(inputFilesType); 
            } 
                
            files = inputFilesType.getFile();
                
            FileDesc fileDesc = objFactory.createFileDesc();
                
            fileDesc.setName(inputFile); 
            files.add(fileDesc);
                
        } catch (JAXBException jbe) {

        	logger.log(Level.SEVERE, "An error occured while setting checkpoing input file name (see details below)!", jbe);
            throw new Exception(jbe);
        }
    }
    
    public String getCheckpointOutputFileName() {
            
         RecoveryInfo recoveryInfo = appDsc.getRecovery();
        
        if (recoveryInfo == null)
            return null;
            
        Files outputFilesType = recoveryInfo.getCheckpointOutputFiles();
            
        if (outputFilesType != null) {
            
            Iterator iter = outputFilesType.getFile().iterator();
         
            if (iter.hasNext()) {
                FileDesc fileDesc = (FileDesc) iter.next(); 
    
                // only the first one
                return fileDesc.getName();
            }
        }
            
        return null;
    }  
    
    public String[] getCheckpointOutputFileNames() {
          
        String[] fileNames;
        FileDesc fileDesc;
          
        RecoveryInfo recoveryInfo = appDsc.getRecovery();
        
        if (recoveryInfo == null)
            return new String[0];
            
        Files outputFilesType = recoveryInfo.getCheckpointOutputFiles();
           
        if (outputFilesType != null) {
               
            Iterator iter = outputFilesType.getFile().iterator();
            int index = 0;

            fileNames = new String[outputFilesType.getFile().size()];
                
            while (iter.hasNext()) {
                   
                fileDesc = (FileDesc) iter.next(); 
                fileNames[index++] = fileDesc.getName();
                     
            }
            return fileNames;
        }
       return new String[0];
    }
        
    public void setCheckpointOutputFileName(String inputFile) throws Exception {
            
        List  files; 
        Files outputFilesType;
        
        try{
           RecoveryInfo recoveryInfo = appDsc.getRecovery();
            
            if (recoveryInfo == null) {
                
                recoveryInfo = createRecoveryInfo();
                appDsc.setRecovery(recoveryInfo);
            }
                
            outputFilesType = recoveryInfo.getCheckpointOutputFiles();
            
            if (outputFilesType == null){
                
                outputFilesType = createFiles();
                recoveryInfo.setCheckpointOutputFiles(outputFilesType); 
            } 
                
            files = outputFilesType.getFile();
                
            FileDesc fileDesc = objFactory.createFileDesc();
                
            fileDesc.setName(inputFile); 
            files.add(fileDesc);
                
        } catch (JAXBException jbe) {

        	logger.log(Level.SEVERE, "An error occured while setting checkpoing output file name (see details below)!", jbe);
            throw new Exception(jbe);
        }
    }
    // -----------------------------
    // Performance Parameter Section
    // -----------------------------    
    public String[] getPerformanceParameterNames() {
	    	
        String[] ret;
	        
        Performance perf = appDsc.getPerformance();
        PerformanceParameters perfParams;
	         
        if (perf == null) { 
	         
            return new String[0];
        }
           
        perfParams = perf.getPerformanceParameters();
        if (perfParams == null) {
	        
            return new String[0];
        }
	       
        List listParam = perfParams.getPerformanceParameter();
	       
        ret = new String[ listParam.size()];
	        
        Iterator iter = listParam.iterator();  
	       
        int index = 0;

        while (iter.hasNext()) {
	           
            ret[index++] = ((PerformanceParameter) iter.next()).getName();
        } 
	       
        return ret;
    }
	    
    public void setPerformanceParameterNames(String[] names) throws Exception {
	        
        Performance perf = appDsc.getPerformance();
        PerformanceParameters perfParams;
	       
        if (perf == null) { 
	           
            perf = createPerformance(); 
            perf.setMachineParameters(createMachineParameters());
            perf.setProviderParameters(createProviderParameters());
            appDsc.setPerformance(perf);
        }
	       
        perfParams = perf.getPerformanceParameters();
	       
        if (perfParams == null) {
            perfParams = createPerformanceParameters();
            perf.setPerformanceParameters(perfParams);
        }
	    
	    perfParams.getPerformanceParameter().clear();
	    
	    if(names == null)
	      names = new String[0];
	    
        for (int i = 0; i < names.length; i++) {
            perfParams.getPerformanceParameter().add(createPerformanceParameter(names[i]));
        }
    }
	    
    public int[] getNumberOfNodes() {
		
        int[] nodes;
	        
        Performance perf = appDsc.getPerformance();
        MachineParameters machineParams;
        MachineParameters.NumberOfNodesType numNodes; 
	       
        if (perf == null) { 
	         
            return new int[0];
        }
           
        machineParams = perf.getMachineParameters();
        if (machineParams == null) {
	        
            return new int[0];
        }
	       
        numNodes = machineParams.getNumberOfNodes();
        if (numNodes == null) {
	        
            return new int[0];
        }
	       
        List listNumber = numNodes.getNumber();
	       
        nodes = new int[ listNumber.size()];
	        
        Iterator iter = listNumber.iterator();  
	       
        int index = 0;

        while (iter.hasNext()) {
	           
            nodes[index++] = ((Integer) iter.next()).intValue(); 
        } 
	       
        return nodes;
    }

    public void setNumberOfNodes(int[] nodes) throws Exception {
	        
        Performance perf = appDsc.getPerformance();
        MachineParameters machineParams;
        MachineParameters.NumberOfNodesType numNodes;
	      
        if (perf == null) { 
	           
            perf = createPerformance(); 
            perf.setPerformanceParameters(createPerformanceParameters()); 
            perf.setProviderParameters(createProviderParameters());
            appDsc.setPerformance(perf);
        }
	       
        machineParams = perf.getMachineParameters();
	       
        if (machineParams == null) {
	       
            machineParams = createMachineParameters();
            perf.setMachineParameters(machineParams);
        }
	       
        numNodes = machineParams.getNumberOfNodes(); 
	     
        if (numNodes == null) {	       
            numNodes = createMachineParametersNumberOfNodesType(); 
            machineParams.setNumberOfNodes(numNodes);
        }  
        
        numNodes.getNumber().clear();  
        
        if (nodes == null)
            nodes = new int[0];
             
        for (int i = 0; i < nodes.length; i++) {
            numNodes.getNumber().add(new Integer(nodes[i])); 
        }
    }
  
    public String getBusinessModelClass() {
			
        Performance perf = appDsc.getPerformance();
        ProviderParameters providerParams;
	       
        if (perf == null) {  
            return null;
        }
	       
        providerParams = perf.getProviderParameters();
	       
        if (providerParams == null) {  
            return null;
        }
	       
        return providerParams.getBusinessModelClass();	
    }
		
    public void setBusinessModelClass(String businessModelClass) throws Exception {
		    
        Performance perf = appDsc.getPerformance();
        ProviderParameters providerParams;
	       
        if (perf == null) { 
	           
            perf = createPerformance(); 
            perf.setPerformanceParameters(createPerformanceParameters());
            perf.setMachineParameters(createMachineParameters());
            perf.setProviderParameters(createProviderParameters());
            appDsc.setPerformance(perf);
        }
	       
        providerParams = perf.getProviderParameters();
	       
        providerParams.setBusinessModelClass(businessModelClass);
    }
     
    public String getBusinessModelConfiguration() {
      
        Performance perf = appDsc.getPerformance();
        ProviderParameters providerParams;
	       
        if (perf == null) {  
            return null;
        }
	       
        providerParams = perf.getProviderParameters();
	       
        if (providerParams == null) {  
            return null;
        }
	       
        return providerParams.getBusinessModelConfiguration();  
    } 
    
    public void setBusinessModelConfiguration(String businessModelConfig)throws Exception {
    
        Performance perf = appDsc.getPerformance();
        ProviderParameters providerParams;
	       
        if (perf == null) { 
	           
            perf = createPerformance(); 
            perf.setPerformanceParameters(createPerformanceParameters());
            perf.setMachineParameters(createMachineParameters());
            perf.setProviderParameters(createProviderParameters());
            appDsc.setPerformance(perf);
        }
	       
        providerParams = perf.getProviderParameters();
	       
        providerParams.setBusinessModelConfiguration(businessModelConfig);
    
    } 
     
    public String getPerformanceModelClass() {
			
        Performance perf = appDsc.getPerformance();
        ProviderParameters providerParams;
	       
        if (perf == null) {  
            return null;
        }
	       
        providerParams = perf.getProviderParameters();
	       
        if (providerParams == null) {  
            return null;
        }
	       
        return providerParams.getPerformanceModelClass();	
    }
		
    public void setPerformanceModelClass(String perfModelClass) throws Exception {
		    
        Performance perf = appDsc.getPerformance();
        ProviderParameters providerParams;
	       
        if (perf == null) { 
	           
            perf = createPerformance(); 
            perf.setPerformanceParameters(createPerformanceParameters());
            perf.setMachineParameters(createMachineParameters());
            perf.setProviderParameters(createProviderParameters());
            appDsc.setPerformance(perf);
        }
	       
        providerParams = perf.getProviderParameters();
	       
        providerParams.setPerformanceModelClass(perfModelClass);
    }
    
    public String getPerformanceModelConfiguration() {
        
        Performance perf = appDsc.getPerformance();
        ProviderParameters providerParams;
	       
        if (perf == null) {  
            return null;
        }
	       
        providerParams = perf.getProviderParameters();
	       
        if (providerParams == null) {  
            return null;
        }
	       
        return providerParams.getPerformanceModelConfiguration();	  
    }
    
    public void setPerformanceModelConfiguration(String perfModelConfig)throws Exception {
        
        Performance perf = appDsc.getPerformance();
        ProviderParameters providerParams;
	       
        if (perf == null) { 
	           
            perf = createPerformance(); 
            perf.setPerformanceParameters(createPerformanceParameters());
            perf.setMachineParameters(createMachineParameters());
            perf.setProviderParameters(createProviderParameters());
            appDsc.setPerformance(perf);
        }
	       
        providerParams = perf.getProviderParameters();
	       
        providerParams.setPerformanceModelConfiguration(perfModelConfig);
    
    }
    
    public String getComputeResourceManagerClass() {
			
        Performance perf = appDsc.getPerformance();
        ProviderParameters providerParams;
	       
        if (perf == null) {  
            return null;
        }
	       
        providerParams = perf.getProviderParameters();
	       
        if (providerParams == null) {  
            return null;
        }
	       
        return providerParams.getComputeResourceManagerClass();	
    }

    public void setComputeResourceManagerClass(String crmClass) throws Exception {
		    
        Performance perf = appDsc.getPerformance();
        ProviderParameters providerParams;
	       
        if (perf == null) { 
	           
            perf = createPerformance(); 
            perf.setPerformanceParameters(createPerformanceParameters());
            perf.setMachineParameters(createMachineParameters());
            perf.setProviderParameters(createProviderParameters());
            appDsc.setPerformance(perf);
        }
	       
        providerParams = perf.getProviderParameters();
	       
        providerParams.setComputeResourceManagerClass(crmClass);
    }

    public String toString() {
            
        StringWriter appDscWriter = new StringWriter(); 
            
        try {
             
            marshaller.marshal(appDsc, appDscWriter);
             
            return appDscWriter.toString();
           
        } catch (JAXBException je) {

        	logger.log(Level.SEVERE, "An error occured while converting XML to String (see details below)!", je);
            return je.toString();
        }
         
    }
    
    // Create Methods

    private Files createFiles() throws JAXBException {
             
        return  objFactory.createFiles();
               
    }
     
    private void createJobScrParams()throws JAXBException {
             
        JobScrParams jobParams = objFactory.createJobScrParams();
           
        configType.setJobScriptParameters(jobParams);
           
        appDsc.setConfiguration(configType);
             
    }
      
     
    private void createInfoType() throws JAXBException {
              
        ApplicationType.InfoType infoType = objFactory.createApplicationTypeInfoType();
           
        appDsc.setInfo(infoType);
              
    }
     
    private StatusInfo createStatus() throws JAXBException {
             
        StatusInfo statusInfoType;
           
        statusInfoType = configType.getStatusInfo();
           
        if (statusInfoType == null) {
           
            statusInfoType = objFactory.createStatusInfo();
               
            NameInfo nameInfo = createNameInfo();
               
            nameInfo.setName("not configured"); 
              
            statusInfoType.setStatusFile(nameInfo);
              
            configType.setStatusInfo(statusInfoType);
               
            appDsc.setConfiguration(configType);
        }
           
        return  statusInfoType;
    }
        
    private PathInfo createPathInfo() throws JAXBException {
            
        return objFactory.createPathInfo();
             
    }
        
    private NameInfo createNameInfo() throws JAXBException {
            
        return objFactory.createNameInfo();
             
    }
        
    private void createConfig() throws JAXBException {
            
        configType = objFactory.createConfig();
               
        appDsc.setConfiguration(configType);
             
    }
    
    private RecoveryInfo createRecoveryInfo() throws JAXBException { 
         
        return objFactory.createRecoveryInfo();    
    }
    
    private Performance createPerformance() throws JAXBException { 
         
        return objFactory.createPerformance();    
    }
    
    
    private PerformanceParameters createPerformanceParameters() throws JAXBException { 
         
        return objFactory.createPerformanceParameters();    
    } 
    
    private PerformanceParameter createPerformanceParameter(String name) throws JAXBException { 
         
        PerformanceParameter param = objFactory.createPerformanceParameter();    
        
        param.setName(name);
        
        return param;
    }    
    
    private ProviderParameters createProviderParameters() throws JAXBException { 
         
        ProviderParameters provider = objFactory.createProviderParameters();    
         
        return provider;
    } 
    
    private MachineParameters createMachineParameters() throws JAXBException { 
         
        return objFactory.createMachineParameters();    
    } 
    
    private MachineParameters.NumberOfNodesType createMachineParametersNumberOfNodesType() throws JAXBException { 
         
        return objFactory.createMachineParametersNumberOfNodesType();   
         
    } 
}
